2017-05-04 5 views
1

SQL Server 2008を使用しています。STUFFとFOR XML PATHを使用して1つのフィールドにカンマ区切り文字列を作成するselectステートメントを作成しようとしています。レコードは1つだけですが、31のフィールドがあります。複数のフィールドを持つXMLパスのSQLステートメント

私は月の毎日のsmallintフィールドを持つ1つのテーブルからデータを取り出しています - 0はその日にnoを意味し、1はyesを意味します。 (私はこのテーブルを設計していなかったと、残念ながら、私はそれを変更することはできないのです。)これと同じように:ように

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 

そして、z31stを介してすべての道を。

私の文は、整数変数@order_snbrと@admin_nbrを渡しています。これは常に1行を返します。

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 

これはそうのような結果を生成します。私が望む何

1st14th28th 

はこれです:

1st, 14th, 28th 

すべてのヘルプははるかに高く評価されるだろう! STUFFまたはFOR XML PATHなしでこれを行うより良い方法があれば、私は切り替えてもうれしいです。

答えて

1

おそらく、別のアプローチ

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 

戻り

enter image description here

+0

これは本当に賢いです! – n8wrl

+0

@ n8wrl Shhhh ...私の妻に伝えないでください。彼女は私にものをすることを望みます。 –

+0

素晴らしい!作品は夢のように.... –

関連する問題