Skip to content
Advertisement

sql extract multiple words from one cell

I have a column that has some text written in it, including serial numbers. What I want to do is to extract the serial numbers , when they exists. I managed to extract only the first one. This works great if there is only one SN in it, otherwise the rest are not shown.

For example I have this:

1 {rtf1ansiansicpg1252deff0deflang1031{fonttbl{f0fnilfprq15fcharset0 Arial;}}  viewkind4uc1pardf0fs16 HPE Gen8 300GB 6G SAS 10K  par SN:tab 2C7713I0VG  par tab 2C7713I0WX  par tab 2C7712I0HP  par tab 2C7713I0WS  par }  
2 {rtf1ansiansicpg1252deff0deflang1031{fonttbl{f0fnilfprq15fcharset0 Arial;}}  viewkind4uc1pardf0fs16 HGST Ultrastar 7K4000 2TB HDD  par SN:tab P5JKS38W  par }  
3 {rtf1ansiansicpg1252deff0deflang1031{fonttbl{f0fnilfprq15fcharset0 Arial;}}  viewkind4uc1pardf0fs16 Microsoft Project Standard 2016  par SN:tab 3BN8W-YBKJQ-3JF76-GKHVV-PWFPJ  par ID:tab ObenAT1d0220  par }
4 {rtf1ansiansicpg1252deff0deflang1031{fonttbl{f0fnilfprq15fcharset0 Arial;}}  viewkind4uc1pardf0fs16 ClientID:tab AuttechGR0201  par SN:tab 737NH-HVYGX-QYTFF-VGDG4-HQWCG  par }
5 {rtf1ansiansicpg1252deff0deflang1031{fonttbl{f0fnilfprq15fcharset0 Arial;}}  viewkind4uc1pardf0fs16 HGST Ultrastar 7K4000 2TB HDD }

I need to split the each SN into new row, like this:

SerialNumbers
2C7713I0VG
2C7713I0WX
2C7712I0HP
2C7713I0WS
P5JKS38W
3BN8W-YBKJQ-3JF76-GKHVV-PWFPJ
737NH-HVYGX-QYTFF-VGDG4-HQWCG    

This is what I did so far:

SELECT 
ABFPosLangText, 
SUBSTRING(
    ABFPosLangText, 
    CHARINDEX('par SN:tab', ABFPosLangText)+ LEN('par SN:tab'), --begining of the first serial number
    CHARINDEX('', ABFPosLangText, CHARINDEX('par SN:tab', ABFPosLangText))- CHARINDEX('par SN:tab', ABFPosLangText)+ LEN('par SN:tab')

FROM ABFPos

 WHERE ABFPosLangText LIKE ('%SN:%')

As it can be seen , the serial nums are in between tab and par.

I used par SN:tab – because I was trying to get any result

I am still a newbie when it comes to SQL, so any help would be great.

EDIT

using the answer from @Tyron78 I tried to get my result, but it still gives me errors. I do have to point out that I did change the code a little bit because I use MS SQL – instead of TRIM func I used RTRIM(LTRIM()) – which should work – but I still get the first part of the text in the result.

When the query is implemented on the first line I get the following result:

SerialNr
{rtf1ansiansicpg1252deff0deflang1031{fonttbl{f0fnilfprq15fcharset0 Arial;}} viewkind4uc1df0fs16 HPE Gen8 300GB 6G SAS 10K  SN:
 2C7713I0VG
 2C7713I0WX
 2C7712I0HP
 2C7713I0WS  }

AND this is the msg I get : Message 9421, level 16, status 1, line 1 XML analysis: line 2, character 48, invalid name character.

Advertisement

Answer

You can try and use a mixture of XML and CrossApply, such as follows:

DECLARE @t TABLE(
ID int, MyString nvarchar(1000)
)

INSERT INTO @t VALUES
(1, N'{rtf1ansiansicpg1252deff0deflang1031{fonttbl{f0fnilfprq15fcharset0 Arial;}}  viewkind4uc1pardf0fs16 HPE Gen8 300GB 6G SAS 10K  par SN:tab 2C7713I0VG  par tab 2C7713I0WX  par tab 2C7712I0HP  par tab 2C7713I0WS  par }')
,(2, N'{rtf1ansiansicpg1252deff0deflang1031{fonttbl{f0fnilfprq15fcharset0 Arial;}}  viewkind4uc1pardf0fs16 HGST Ultrastar 7K4000 2TB HDD  par SN:tab P5JKS38W  par }')
,(3, N'{rtf1ansiansicpg1252deff0deflang1031{fonttbl{f0fnilfprq15fcharset0 Arial;}}  viewkind4uc1pardf0fs16 HGST Ultrastar 7K4000 2TB HDD}')

;WITH cte1 AS(
SELECT ID, SUBSTRING(MyString, CHARINDEX('SN:', MyString)+3, LEN(MyString)-CHARINDEX('SN:', MyString)-2) AS MyString
  FROM @t
  WHERE CHARINDEX('SN:', MyString) > 0
)
select 
    a.value('.', 'varchar(max)') AS SerialNr
from
    (select cast('<M>' + rtrim(ltrim(REPLACE(REPLACE(REPLACE(REPLACE(MyString, 'tab', '</M><M>'),'par',''),'{',''),'}',''))) + '</M>' AS XML) as col from cte1) as A
    CROSS APPLY A.col.nodes ('/M') AS Split(a)
where NULLIF(a.value('.', 'varchar(max)'),'') IS NOT NULL

However, this will only work if SN is the last part of your string. If anything else follows in the string, you will have to consider this in your substring in cte1.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement