0

I'm looking for a little help in splitting apart a field that uses multiple delimiters in a sql function/ statement. I've followed a few examples already listed HERE

here that work very well with a single delimiter. However I need to split apart a field that is based on the following. its format would be qty x itemno description, qty x itemno description, etc. I therefore need to break apart the statement on the first ' x' the second space ' ' and the final comma.. I figure I can split this based on a regular expression statement but unsure about how to go about it..

could anyone help?

    OnSameLine = substring( ( SELECT ', ' + 
                 coalesce (CAST(CNT.qty AS varchar(1000)), '') +                  
                 ' x ' + '['+ coalesce (CNT.Itemno,'') + ']' + 
                 ' ' + coalesce (STK.Desc#1,'')

format I need..

PK qty itemno description
PK qty itemno description 

etc..

0

2 Answers 2

1

Try this:

Based on article from here

;with T(id, Cols) as
(
  select 1, '10 x 1234 description1,11 x 456 description2' 
  UNION ALL
  select 2, '40 x 123478 description3,51 x 45678 description4' 
),
--first split all comma separated into different rows
CTE2 AS 
(
    SELECT id, 
    CAST(N'<H><r>' + replace(Replace(Vals.a.value('.', 'NVARCHAR(50)'),
        ' ','|'), '|', '</r><r>') + '</r></H>' as XML) Cols
    FROM
    (
    SELECT *,CAST (N'<H><r>' + Replace(cols,',','</r><r>') + 
        '</r></H>' AS XML) AS [vals]
    FROM T) d
    CROSS APPLY d.[vals].nodes('/H/r') Vals(a)
)
-- split all ' ' demilited values now
SELECT distinct id, Vals.a.value('(/H/r)[1]', 'VARCHAR(100)') AS Qty,
Vals.a.value('(/H/r)[2]', 'VARCHAR(100)') AS X,
Vals.a.value('(/H/r)[3]', 'VARCHAR(100)') AS ItemNo,
Vals.a.value('(/H/r)[4]', 'VARCHAR(100)') AS Description
FROM
(
SELECT *
FROM CTE2) d
CROSS APPLY d.[cols].nodes('/H/r') Vals(a)
Sign up to request clarification or add additional context in comments.

3 Comments

+1 for splitting by space into different columns. I am not sure if it is the the requirement. I have exchanged Qty and X after first split. Checkout mine.
thanks I just tried this and forgot I have some old historical data in the field that does not obey the instructed format.. apologies so I hit an XML parsing: line 1, character 54, illegal name character. is there a way to return the original field if the format is not correct. else this looks just what I need
I isolated a valid dataset and it's working bar the qty column which is blank and hence all columns move right by one. I figure it's this line causing the error.. Vals.a.value('(/H/r)[1]', 'VARCHAR(100)') AS Qty,
0

If you just want to split by , and exchange Qty and PK, try this;

DECLARE @S VARCHAR(max)= 'Q1 PK1 ITM1 D1,Q2 PK2 ITM2 D2'

DECLARE @X XML
SELECT @X  = '<myxml><n><d>' + 
             REPLACE (@S,',','</d></n><n><d>') + '</d></n></myxml>'


SELECT SUBSTRING(x,firstSpace,secondSpace-firstSpace) + ' ' + 
       SUBSTRING(x,1,firstSpace) + ' ' + 
       SUBSTRING(x,secondSpace,len(x))
FROM ( --Getting CharIndex of first and second spaces
    SELECT x, CHARINDEX(' ',x,1) firstSpace, CHARINDEX(' ',x,CHARINDEX(' ',x,1)+1) secondSpace
    FROM ( --Spliting by "," into records 
        SELECT C.value('d[1]','VARCHAR(50)') x
        FROM @X.nodes('/myxml/n') Cols (C) ) T1
) T2

SQL Fiddle here

--Data
'Q1 PK1 ITM1 D1,Q2 PK2 ITM2 D2'

--Results
'PK1 Q1 ITM1 D1'
'PK2 Q2 ITM2 D2'

If you want to split them into columns then try this;

DECLARE @S VARCHAR(500)= 'Q1 PK1 ITM1 D1,Q2 PK2 ITM2 D2'
DECLARE @X XML

SELECT @X  = '<myxml><n><d>' + 
REPLACE(REPLACE (@S,',','</d></n><n><d>'), ' ', '</d><d>') + 
'</d></n></myxml>'


SELECT  C.value('d[2]','VARCHAR(50)') PK,
        C.value('d[1]','VARCHAR(50)') Qty,
        C.value('d[3]','VARCHAR(50)') Item,
        C.value('d[4]','VARCHAR(50)') Description
        FROM @X.nodes('/myxml/n') Cols (C)

SQL Fiddle here

--Data 
'Q1 PK1 ITM1 D1,Q2 PK2 ITM2 D2'

--Results
PK1 | Q1 | ITM1 | D1
PK2 | Q2 | ITM2 | D2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.