web-dev-qa-db-ja.com

SQLサーバーの結合テーブルとピボット

データを含む2つのテーブルがあります

表1

    ---------------------------------------------------
    | SALEID | SOLDBY | SALEPRICE | MARGIN |   DATE   |
    |  1     |  'aa'  |  10,000   |   10   | 2013-1-1 |
    |  2     |  'bb'  |  25,000   |    5   | 2013-5-1 |

表2

    ---------------------------------------------------
    | SALEITEMID | SALEID | SALEPRICE | CATEGORY |
    |  1         |  1     |   6,000   | BOOKS    |
    |  2         |  1     |   4,000   | PRINTING |
    |  3         |  2     |   5,000   | BOOKS    |
    |  4         |  2     |   12,000  | PRINTING |
    |  5         |  2     |   8,000   | DVD      |

生成するクエリが必要です

TAB

    --------------------------------------------------------------------------------
    | SALEID | SOLDBY | SALEPRICE | MARGIN |   DATE   |  BOOKS  | PRINTING | DVD
    |  1     |  'aa'  |  10,000   |   10   | 2013-1-1 |  6,000  |  4,000   | 0
    |  2     |  'bb'  |  25,000   |    5   | 2013-5-1 |  5,000  | 12,000   | 8,000

私はピボットにかなり慣れていないので、ピボットがこれに適しているかどうかはわかりません。

25
Null Head

これは動作するはずです:

_WITH Sales AS (
   SELECT
      S.SaleID,
      S.SoldBy,
      S.SalePrice,
      S.Margin,
      S.Date,
      I.SalePrice,
      I.Category
   FROM
      dbo.Sale S
      INNER JOIN dbo.SaleItem I
         ON S.SaleID = I.SaleID
)
SELECT *
FROM
   Sales
   PIVOT (Max(SalePrice) FOR Category IN (Books, Printing, DVD)) P
;
_

または交互に:

_SELECT
   S.SaleID,
   S.SoldBy,
   S.SalePrice,
   S.Margin,
   S.Date,
   I.Books,
   I.Printing,
   I.DVD
FROM
   dbo.Sale S
   INNER JOIN (
      SELECT *
      FROM
         (SELECT SaleID, SalePrice, Category FROM dbo.SaleItem) I
         PIVOT (Max(SalePrice) FOR Category IN (Books, Printing, DVD)) P
   ) I ON S.SaleID = I.SaleID
;
_

これらは同じ結果セットを持ち、実際にはクエリオプティマイザーによって同じように扱われる場合がありますが、そうでない場合があります。 Saleテーブルに条件を設定し始めると、大きな違いが出てきます。どのクエリがよりよく機能するかをテストして確認する必要があります。

ただし、プレゼンテーション層でピボットを行うことをお勧めしますか?たとえば、SSRSを使用している場合、すべてのピボットを実行するマトリックスコントロールを使用するのは非常に簡単です。新しいCategoryを追加すると、すべてのSQLコードを変更する必要がなくなるため、これが最適です。

ピボットする列名を動的に検索する方法がありますが、動的SQLが含まれます。可能ですが、最善の方法としてもお勧めしません。

couldが機能するもう1つの方法は、このクエリを前処理することです。つまり、ビューを書き換えるCategoryテーブルにトリガーを設定します存在するすべての既存のカテゴリ。これは、私が言及した他の多くの問題を解決しますが、再び、プレゼンテーション層を使用することが最善です。

:カラム名(以前は値だった)にスペースが含まれているか、数字であるか数字で始まるか、有効な識別子でない場合は、PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P。または、クエリのPIVOT部分に到達する前に値を変更して、文字を追加したりスペースを削除したりして、列リストをエスケープする必要がないようにすることができます。詳細については、SQL Serverのidentifiersのルールを確認してください。

44
ErikE