2017-01-31 8 views
0

特定の行の値を列に転置しようとしています。以下は私のテーブルには、次のようになります。以下はIf文を使用して行を列に変換する

ID Shoe Shirt Hat Socks Pants 
1 Red  3  Black 2  Red 

私が使用していたコードです:

select Max(Case When [Item] = 'Shoe' Then Color End) as Shoe 
    ,Max(Case When [Item] = 'Shirt' Then Quantity End) as Shirt 
    ,Max(Case When [Item] = 'Hat' Then Color End) as Hat 
    ,Max(Case When [Item] = 'Socks' Then Quantity End) as Socks 
    ,Max(Case When [Item] = 'Pants' Then Color End) as Pants 
From Inventory 

問題私が見えるようにテーブルがこれです欲しい

ID Item  Color Quantity 
1 Shoe  Red 
1 Shirt    3 
1 Hat   Black 
1 Socks    2 
1 Pants  Red 

私のコードでは行の値が時々列の色であり、それ以外の時は列の数量です。私は、値を持つ列にしか使用できないようにしたいと考えています。私の実際のselectステートメントは50以上のMax(Case)ステートメントを持っていますので、もし多少の場合は、if文をオーバーライドすることができ、各行に1つずつ行う必要はありません!

+0

「正しい」値がどの列に含まれているかをどのように知っていますか?他の列はNULLですか?次に、合体(Color、Quantity)またはisnull(Color、Quantity)を使用することができます。 –

+0

「Color」と「Quantity」の両方に値がある場合はありません。 – Stephen

+0

であるため、nullになることはありませんが、Colorは空白( "")になります。また、Quantityは0になります。いいえ、両方に値を設定することはできません。 –

答えて

2

をチェックする必要があるだろう、他の値がnullの場合、こののみ動作ことに留意すべきです。

以下のサブクエリでは、CONCAT()を使用しており、NULLの値が適切に処理されています。

Declare @Filter varchar(100) = 'Shoe,Socks' 

Declare @SQL varchar(max) 
Select @SQL = 'Select ID,' + '['+Replace(@Filter,',','],[')+']' + ' 
       From (
         Select ID 
          ,Item 
          ,Value = concat(NullIf(Color,''''),NullIf(Quantity,0)) 
         From Inventory 
         Where charindex('',''+Item+'','','','[email protected]+','')>0 
        ) A 
       Pivot (max(Value) For Item in (' + '['+Replace(@Filter,',','],[')+']' + ')) p' 
Exec(@SQL); 

EDIT:トラップ "空" の値にconcat()から

追加NullIf()

+0

これを変更して、ピボットするアイテムを選択できるようにするにはどうすればよいでしょうか。だから私の例では、私は靴と靴下がほしいと思ったらどうしましたか? –

+0

@VBA_SQL_Programmer更新された回答を参照 –

+0

@VBA_SQL_Programmer Select Distinctを削除します。フィルタを適用しているため不要です –

2

共通のテーブル式(CTE)を使用して非ヌル値の列を見つけて、項目上にすべてPIVOTを見つけた場合はどうでしょうか?あなたがダイナミックバージョンをしたい場合はそうでなければ、「」または0

;WITH CTE 
AS 
(
    SELECT ID, Item, COALESCE(Color, CAST(Quantity AS VARCHAR(10))) AS Value 
    FROM Inventory 
) 
select * from CTE 
pivot (max (Value) for Item in ([Shoe],[Shirt],[Hat],[Socks],[Pants])) AS c 
+0

だから私はどのように ""か0をチェックするのですか? –

0

おそらく、項目を値の列にマップする辞書が必要です。たとえば、

select Max(Case When [Item] = 'Shoe' Then 
      Case col when 'Color' then Color else Quantity End 
      End) as Shoe 
    ,Max(Case When [Item] = 'Shirt' Then 
      Case col when 'Color' then Color else Quantity End 
      End) as Shirt 
    ,Max(Case When [Item] = 'Hat' Then 
      Case col when 'Color' then Color else Quantity End 
      End) as Hat 
    ,Max(Case When [Item] = 'Socks' Then 
      Case col when 'Color' then Color else Quantity End 
      End) as Socks 
    ,Max(Case When [Item] = 'Pants' Then 
      Case col when 'Color' then Color else Quantity End 
      End) as Pants 
From (
    select i.*, col 
    from Inventory i 
    join (
     values ('Shoe', 'Color') 
     ,('Shirt', 'Quantity') 
     ,('Hat', 'Color') 
     ,('Socks', 'Quantity') 
     ,('Pants', 'Color') 
     ) dict (itm, col) on dict.itm=t.item 
) t 
関連する問題