2016-08-19 8 views
0

これは、このクエリを変更することをお勧めすることができ、最も簡単な方法は何かテーブル構造を変更することなく、SQL Serverの2014フラット化SQLクエリ

である(出力は、以下に示す)

select 
    a.Id, a.Sku, a.lbl, 
    Desc, 
    (select b.Valu where b.Attribute = 'rel') as 'rel', 
    (select b.Valu where b.Attribute = 'uom') as 'uom', 
    (select b.Valu where b.Attribute = 'clas') as 'clas' 
from 
    items a 
join 
    itemattributes b on b.id = a.id 

出力:

この出力に
id sku  lbl   desc rel  uom  clas 
2 X111 X111-456789 red NULL NULL C 
2 X111 X111-456789 red NULL Cs  NULL 
2 X111 X111-456789 red 3  NULL NULL 
3 X222 X222-567890 white NULL NULL B 
3 X222 X222-567890 white NULL Cs  NULL 
3 X222 X222-567890 white 2  NULL NULL 
4 X333 X333-678901 blue NULL NULL C 
4 X333 X333-678901 blue NULL Ea  NULL 
4 X333 X333-678901 blue 9  NULL NULL 

id sku  lbl   desc rel  uom  clas 
2 X111 X111-456789 red 3  Cs  C 
3 X222 X222-567890 white 2  Cs  B 
4 X333 X333-678901 blue 9  Ea  C 
+0

テーブルとインデックスのサイズによっては、最適化のためにHLGEMのソリューション(下記)を使用します。 –

+0

ありがとうございます。すべての素晴らしい入力。私は自分自身がこれを書いているのを見つけようとしていました。しかし、VKPは以前私が何をしたかを思い出させます。私は、時には、複数の結合がどこで私に対して働き始めるのかと疑問に思います。 – Steve

答えて

3

条件付き集約を使用して、異なる属性値でグループ化できます。あなたが複数の操作を行うことができ

select a.Id 
    , a.Sku 
    , a.lbl 
    , [Desc] 
    , max(case when b.Attribute = 'rel' then b.Valu end) as rel 
    , max(case when b.Attribute = 'uom' then b.Valu end) as uom 
    , max(case when b.Attribute = 'clas' then b.Valu end) as clas 
from items a  
join itemattributes b 
    on b.id = a.id 
group by a.Id 
    , a.Sku 
    , a.lbl 
    , [Desc] 
1

が加入:

select a.Id 
    , a.Sku 
    , a.lbl 
    , Desc 
    , b.Valu as 'rel' 
    , c.Valu as 'uom' 
    , d.Valu as 'clas' 
from items a   
    join itemattributes b on b.id = a.id  
    join itemattributes c on c.id = a.id  
    join itemattributes d on d.id = a.id 
where b.Attribute = 'rel' 
    and c.Attribute = 'uom' 
    and d.Attribute = 'clas' 

あなたはまた、完全に参加し排除することができるはずです。

select a.Id 
    , a.Sku 
    , a.lbl 
    , Desc 
    , (select b.Valu from itemattributes b where b.id = a.id and b.Attribute = 'rel') as 'rel' 
    , (select b.Valu from itemattributes b where b.id = a.id and b.Attribute = 'uom') as 'uom' 
    , (select b.Valu from itemattributes b where b.id = a.id and b.Attribute = 'clas') as 'clas' 
from items a 
+0

@vkpは別の良いオプションを示しています>> GROUP BY –

+1

絶対的な個人的な好みでは、クエリの意図を読みやすくするためにJoin節にWHERE条件を入れて、HLGEMはこれを左のジョインに簡単に切り替えることができます。不足している。 – Matt

+0

@mattはい。 HLGEMはその例を与えた。 6人は片方、もう半分はもう片方。 –

3

をあなたは試みることができる:

select a.Id 
    , a.Sku 
    , a.lbl 
    , Desc 
    , rel.Valu as 'rel' 
    , uom.Valu as 'uom' 
    , clas.Valu as 'clas' 
from items a  
join itemattributes rel 
    on rel.id = a.id and rel.Attribute = 'rel' 
join itemattributes uom 
    on uom.id = a.id and uom.Attribute = 'uom' 
join itemattributes clas 
    on clas.id = a.id and clas.Attribute = 'clas' 

これをあなたはレコードがほしいと仮定しますこれらは3つの値をすべて持ちます。これが本当の仮定でない場合は、左の結合を試してください。注記左結合を使用する必要がある場合は、結合に属性を入れて簡単に作成できます。内部結合を使用する場合は、それらをwhere句に入れることができます。