1

I am using SQL Server 2008. I am attempting to write a select statement using STUFF and FOR XML PATH to create a comma separated string in one field. There is only ONE record but 31 fields.

I'm pulling the data from 1 table which has a smallint field for each day of the month - 0 means no for that day, 1 means yes. (I did not design this table and unfortunately I am not allowed to change it.) Like so:

z1st   z2nd   z3rd   z4th   z5th   z6th   z7th   z8th   z9th   z10th
------ ------ ------ ------ ------ ------ ------ ------ ------ ------
0      1      0      0      0      0      0      0      0      0
0      0      0      0      1      0      0      0      0      1
0      0      1      0      0      0      0      0      0      0
0      0      0      1      0      0      0      0      0      0
0      1      0      0      0      0      0      0      0      1

And so on, all the way through z31st.

My statement is passing integer variables @order_snbr and @admin_nbr, which will always return a single row.

DECLARE @strSelectedDayList AS VARCHAR(MAX)

SELECT @strSelectedDayList = STUFF((SELECT ', ' + CASE WHEN td1.z1st = 1 THEN '1st' END
, CASE WHEN td1.z2nd = 1 THEN '2nd' END
, CASE WHEN td1.z3rd = 1 THEN '3rd' END
, CASE WHEN td1.z4th = 1 THEN '4th' END
, CASE WHEN td1.z5th = 1 THEN '5th' END
, CASE WHEN td1.z6th = 1 THEN '6th' END
, CASE WHEN td1.z7th = 1 THEN '7th' END
, CASE WHEN td1.z8th = 1 THEN '8th' END
, CASE WHEN td1.z9th = 1 THEN '9th' END
, CASE WHEN td1.z10th = 1 THEN '10th' END
, CASE WHEN td1.z11th = 1 THEN '11th' END
, CASE WHEN td1.z12th = 1 THEN '12th' END
, CASE WHEN td1.z13th = 1 THEN '13th' END
, CASE WHEN td1.z14th = 1 THEN '14th' END
, CASE WHEN td1.z15th = 1 THEN '15th' END
, CASE WHEN td1.z16th = 1 THEN '16th' END
, CASE WHEN td1.z17th = 1 THEN '17th' END
, CASE WHEN td1.z18th = 1 THEN '18th' END
, CASE WHEN td1.z19th = 1 THEN '19th' END
, CASE WHEN td1.z20th = 1 THEN '20th' END
, CASE WHEN td1.z21st = 1 THEN '21st' END
, CASE WHEN td1.z22nd = 1 THEN '22nd' END
, CASE WHEN td1.z23rd = 1 THEN '23rd' END
, CASE WHEN td1.z24th = 1 THEN '24th' END
, CASE WHEN td1.z25th = 1 THEN '25th' END
, CASE WHEN td1.z26th = 1 THEN '26th' END
, CASE WHEN td1.z27th = 1 THEN '27th' END
, CASE WHEN td1.z28th = 1 THEN '28th' END
, CASE WHEN td1.z29th = 1 THEN '29th' END
, CASE WHEN td1.z30th = 1 THEN '30th' END
, CASE WHEN td1.z31st = 1 THEN '31st' END
FROM TableDays td1 WITH(NOLOCK) 
WHERE td1.order_snbr = td2.order_snbr 
AND td1.admin_nbr = td2.admin_nbr 
FOR XML PATH('')), 1, 1, '')
FROM TableDays td2 WITH(NOLOCK)
WHERE td2.order_snbr = @order_snbr
AND td2.admin_nbr = @admin_nbr

PRINT @strSelectedDayList

This produces a result like so:

1st14th28th

What I would like is this:

1st, 14th, 28th

Any help would be much appreciated! And if there's a better way to do this (without STUFF or FOR XML PATH) I'm happy to switch.

1 Answer 1

1

Perhaps a another approach

Example

Declare @YourTable Table ([z1st] varchar(50),[z2nd] varchar(50),[z3rd] varchar(50),[z4th] varchar(50),[z5th] varchar(50),[z6th] varchar(50),[z7th] varchar(50),[z8th] varchar(50),[z9th] varchar(50))
Insert Into @YourTable Values
 (0,1,0,0,0,1,0,0,0)
,(0,0,0,0,1,0,0,1,0)
,(0,0,1,0,0,0,0,0,0)
,(1,1,1,1,0,0,0,0,0)
,(0,1,0,0,0,0,1,0,1)

Select A.*
      ,C.* 
 From  @YourTable A
 Cross Apply (Select XMLData = cast((select A.* for XML Raw) as xml) ) B
 Cross Apply (
                Select S = Stuff((Select ', ' +replace(Item,'z','')
                 From (
                        Select Item   = attr.value('local-name(.)','varchar(100)')
                         From  B.XMLData.nodes('/row') as A(r)
                         Cross Apply A.r.nodes('./@*') AS B(attr)
                         Where attr.value('local-name(.)','varchar(100)') like 'z[0-9]%'
                           and attr.value('.','varchar(max)') =1
                      ) C1
                 For XML Path ('')),1,2,'') 
             ) C

Returns

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

This is really clever!
@n8wrl Shhhh... Don't tell my wife. She'll want me to do stuff.
@MFLuder Happy it helped

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.