2017-10-10 5 views
1

正しい方法は、これは私の定期的な選択クエリで

category | price | company 
---------+-------+------------- 
Srv  | 1200 | CoA 
Srv  | 2800 | CoB 
EQ  | 5400 | CoA 
Deduc | 400 | CoA 
Deduc | 150 | CoB 

そして、私はこの結果必要があります。

PriceASrv | PriceBSrv | PriceAEQ | PriceBEQ | PriceADeduc | PriceBDeduc 
-----------+-----------+----------+----------+-------------+------------- 
1200  | 2800  | 5400  | NULL  | 400   | 150 

私はピボットを2回必要とするようですが、そうですか?誰にも分かりますか?

+1

存在してよいかわからない場合は、動的なピボットに変換することができますか? –

+0

あなたは2回ピボットする必要はありませんが、以下の例で見られるように、 'company'と' category'の値を連結する必要があります。結果が見つからない場合は、 'categories'と' companies'のすべてが必要なように見えます。会社ごとに1つの行と、カテゴリごとに1つの行を持つ 'category'テーブルを持つ' company'テーブルがありますか? – Beth

+0

SQL言語**は実際には、クエリが実際にどのデータでも実行される前に、コンパイル時にいくつの列とどの型があるかを知る必要があります。あなたがそれを行うことができない場合は、動的SQLを使用して2つのステップでピボットを行うか(最初のステップで「どのように多くの列」に質問するかを決定する)、クライアントコードでピボットを行う必要があります。 –

答えて

1

いいえ、あなたは二度ピボットする必要はありませんが、場合は、動的なクエリが必要になる場合がありますつ以上の企業、OR

  • あなたの会社名を変更することができ、OR
  • 存在でき

    1. カテゴリが変更されることがあります。

    これら3つの条件がすべて偽である場合は、次のクエリのいずれかが動作します:

    DECLARE @T TABLE (Category VARCHAR(10), Price INT, Company CHAR(3)); 
    INSERT @T VALUES 
        ('Srv', 1200, 'CoA'), 
        ('Srv', 2800, 'CoB'), 
        ('EQ', 5400, 'CoA'), 
        ('Deduc', 400, 'CoA'), 
        ('Deduc', 150, 'CoB'); 
    
    -- With PIVOT 
    SELECT * 
    FROM (
        SELECT CatCom = 'Price' + RIGHT(Company, 1) + Category, 
          Price 
        FROM @T) AS T 
    PIVOT (MAX(Price) FOR CatCom IN ([PriceASrv], [PriceBSrv], [PriceAEQ], [PriceBEQ], [PriceADeduc], [PriceBDeduc])) AS P 
    
    -- With CASE aggregation 
    SELECT PriceASrv = MAX(CASE WHEN Category = 'Srv' AND Company = 'CoA' THEN Price END), 
         PriceBSrv = MAX(CASE WHEN Category = 'Srv' AND Company = 'CoB' THEN Price END), 
         PriceAEQ = MAX(CASE WHEN Category = 'EQ' AND Company = 'CoA' THEN Price END), 
         PriceBEQ = MAX(CASE WHEN Category = 'EQ' AND Company = 'CoB' THEN Price END), 
         PriceADeduc = MAX(CASE WHEN Category = 'Deduc' AND Company = 'CoA' THEN Price END), 
         PriceBDeduc = MAX(CASE WHEN Category = 'Deduc' AND Company = 'CoB' THEN Price END) 
    FROM @T; 
    

    三つの条件のいずれかに該当する場合、あなたは基本的になり、動的クエリを(必要があるかもしれませんあなたのニーズに合わせて上記のクエリのいずれかの変更)。

    1

    いいえいいえ、PIVOTは2回必要ありません。以下のクエリを参照してください。あなたが固定された列の数を持っているか、それが動的でくださいあなたはどのように多くの企業が

    Select * from 
    (
    Select 
        [data]='Price' + RIGHT([company],1) +[category] , 
        [price] 
    FROM [prices] 
    INNER JOIN [company] as [co] On [co].[company] = [pr].[company] 
    WHERE [co].[id] In (1,2,3))src 
    PIVOT 
    ( 
    MAX([price]) FOR [data] in (PriceASrv,PriceBSrv,PriceAEQ,PriceBEQ,PriceADeduc,PriceBDeduc) 
    )p 
    

    see working demo

    +0

    でNULLを考慮すると、「INNER」の代わりに「LEFT OUTER JOIN」が必要です。 – Beth

    +0

    実際、もっと複雑です彼はすべての「カテゴリー」がすべての企業と「クロス」して、それに関連した「価格」と「外に出ていった」必要がある。 – Beth

    +1

    @Beth私はデモを作成し、私の変更を元に戻しました。このINNER JOINは動作します – DhruvJoshi

    関連する問題