各年のレコードを列として表示するピボットテーブルを作成するにはどうすればよいですか?

私はこれを行うためにピボットが必要であるとはかなり確信していますが、それを理解できません。 (sql newb)

私はこのようなデータを持っています:

ID    CompanyID    Year    Revenue    Expenses
1     0003         2011    12000      4000
2     0003         2010    9000       6000
3     0003         2009    7000       9000
4     0010         2011    134300     34000
5     0010         2010    43000      46000
6     0010         2009    73000      39000

ピボットを使用して次のようにこの表を表示できますか?

CompanyID    2011-Revenue    2010-Revenue    2009-Revenue    2011-Expenses   2010-Expenses    2009-Expenses
0003         12000           9000            7000            4000            6000             9000
0010         134300          43000           73000           34000           46000            39000

ここまで私がこれまで持っていたことは...

SELECT P1.*
FROM    (SELECT [CompanyID]
            ,CASE P.[Year] WHEN 2011 THEN P.[Revenue] ELSE NULL END AS '2011-Revenue'
            ,CASE P.[Year] WHEN 2010 THEN P.[Revenue] ELSE NULL END AS '2010-Revenue'
    FROM tblRecords P WHERE P.[CompanyID] = @companyID GROUP BY CompanyID, [Year], [Revenue]) AS P1

どちらが帰ってくるのか:

CompanyID    2011-Revenue    2010-Revenue 
0003         12000           NULL
0003         NULL            9000

私の結果にはほとんど問題はありません...

  1. The there is two records for CompanyID 0003 I'd like it to group into one record

  2. I can only choose 1 company at a time, I need to choose multiple. I tried

    FROM tblRecords P
    WHERE P.[CompanyID] IN (@CompanyIDs)
    GROUP BY CompanyID, [Year], [Revenue]) AS P1
    

    Where @CompanyIDs is a string like '0003, 0010' - It didn't fail but the result was just an empty table with the headers and no data..

どのような助けをいただければ幸いですか?または私がピボットを誤解しているかどうか教えてください。

どうもありがとう!

トーマス

編集:Microsoft SQL Server管理Studio 2005 Expressを使用します。

更新2:私は詳細については、テーブルを結合することがわかったが、私はまだコンマで区切られた文字列としてCompanyIDsを渡すことができる必要があります..それについての任意の助けになります。

vvvvvvvv私はこれを下に出しました(すべてが動いたら投稿します)vvvvvvv

更新:それはルーベンが提案したように見えるが、私はちょうど私がこれにもう少し機能が必要だと判断したようだ...私は別のテーブルとこれを結合してヘッダを持つことはできますか

  CompanyID    CompanyName    CompanyAddress    2011-Revenue    2010-Revenue 

CompanyNameとCompanyAddressが別のテーブルから来た場合(tblCompanyDetails)

私は使ってみました:

SELECT *
FROM 
(
    SELECT  CompanyID, tblCompanyDetails.CompanyName, tblCompanyDetails.CompanyAddress, CAST(YEAR AS varchar) + ' - Revenue' Type,
            Revenue Value FROM tblRecords
    FROM tblRecords INNER JOIN tblCompanyDetails ON tblRecords.CompanyID = tblCompanyDetails.CompanyID
    UNION ALL
    SELECT  CompanyID, tblCompanyDetails.CompanyName, tblCompanyDetails.CompanyAddress, CAST(YEAR AS varchar) + ' - Expenses' Type,
            Expenses  Value FROM tblRecords 
    FROM tblRecords INNER JOIN tblCompanyDetails ON tblRecords.CompanyID = tblCompanyDetails.CompanyID
) src
    PIVOT
(
    SUM(Value) for [Type] in
([2011 - Revenue], [2010 - Revenue], [2009 - Revenue],
     [2011 - Expenses], [2010 - Expenses], [2009 - Expenses]
)
) pvt
WHERE CompanyID = @CompanyID

私はエラーが表示されます:

Msg 1038, Level 15, State 4, Procedure spCompare, Line 10
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Add a name or single space as the alias name. 
1
はい、申し訳ありませんが、私はTSQLタグを含んでいましたが、より具体的なものでした。 Micorsoft SQL Server 2005
追加された 著者 tsdexter,
私は一般的にサーバー上のGROUP BYだけを実行し、クライアントアプリケーションで結果をクロス集計する方が柔軟性があると感じています。
追加された 著者 Patrick Honorez,
マイクロソフトのSQLサーバー?
追加された 著者 dan_l,

1 答え

これを試して:

DECLARE @CompanyIDs XML
DECLARE @Records  TABLE
(
    ID int,
    CompanyID char(4),
    Year int,
    Revenue decimal,
    Expenses decimal
)
DECLARE @CompanyDetails TABLE
(
    CompanyID char(4),
    Name varchar(50),
    Address varchar(50)
)

SET @CompanyIDs = '

    0003
    0010
'

INSERT INTO @Records 
(ID, CompanyID, Year, Revenue, Expenses)VALUES 
(1, '0003', 2011, 12000 , 4000 ),
(2, '0003', 2010, 9000  , 6000 ),
(3, '0003', 2009, 7000  , 9000 ),
(4, '0010', 2011, 134300, 34000),
(5, '0010', 2010, 43000 , 46000),
(6, '0010', 2009, 73000 , 39000)

INSERT INTO @CompanyDetails 
(CompanyID, Name, Address) VALUES
('0003', 'Company A', 'A Street'),
('0010', 'Company B', 'B Street')

SELECT *
FROM 
(
    SELECT  CompanyID, CAST(YEAR AS varchar) + ' - Revenue' Type,
            Revenue Value FROM @Records 
    UNION ALL
    SELECT  CompanyID, CAST(YEAR AS varchar) + ' - Expenses' Type,
            Expenses  Value FROM @Records 
) src
PIVOT
(
    SUM(Value) for [Type] in
    ([2011 - Revenue], [2010 - Revenue], [2009 - Revenue],
     [2011 - Expenses], [2010 - Expenses], [2009 - Expenses]
    )
) pvt
JOIN    @CompanyDetails Details
    ON  Details.CompanyId = pvt.CompanyID
WHERE   pvt.CompanyID IN
(
    SELECT  T.C.value('.', 'char(4)')
    FROM    @CompanyIDs.nodes('/filter/CompanyID') T(C)
)

会社フィルタをXMLとして送信し、そのサブセレクトを使用してピボット操作に必要なデータを破棄する必要があります。 JOIN操作の場合は、 pvt 出力を使用してください

2
追加された
しかし、これはうまくいくように見えますが、私は最後にWHERE CompanyID = @ CompanyIDを追加しました。それは年ごとのデータすべてで1つの行を持っていましたが、WHERE CompanyID IN(@CompanyIDs)しかし、空のテーブルが返されました。where節をどのように動作させるか知っていますか?これまで私に教えてくれてありがとう。
追加された 著者 tsdexter,
更新のおかげで私はXMLで試してみる - 本当に助けていただきありがとうございます..私は最初の質問で紛れた少しの更新を見てください...ありがとうございました。
追加された 著者 tsdexter,