web-dev-qa-db-ja.com

不明な列数でのSQLServer2005ピボット

次のようなデータセットを使用しています。

StudentName  | AssignmentName |  Grade
---------------------------------------
StudentA     | Assignment 1   | 100
StudentA     | Assignment 2   | 80
StudentA     | Total          | 180
StudentB     | Assignment 1   | 100
StudentB     | Assignment 2   | 80
StudentB     | Assignment 3   | 100
StudentB     | Total          | 280

割り当ての名前と数は動的であるため、次のような結果を得る必要があります。

Student      | Assignment 1  | Assignment 2  | Assignment 3  | Total
--------------------------------------------------------------------
Student A    | 100           | 80            | null          | 180
Student B    | 100           | 80            | 100           | 280

ここで、理想的には、各割り当てに含める/関連付けることができる「期日」に基づいて列を並べ替えたいと思います。合計は、可能であれば最後にする必要があります(可能であれば、計算してクエリから削除できます)。

ピボットを使用して列に名前を付けるだけで3つの割り当てを行う方法を知っています。動的な方法でそれを実行しようとしていますが、まだ良い解決策は見つかりませんでした。 SQL Server2005でこれを実行しようとしています

[〜#〜]編集[〜#〜]

ポリシーに反するため、動的SQLを使用せずにこれを実装したいのが理想的です。それが不可能な場合は...動的SQLを使用した実例が機能します。

19
Mitchel Sellers

動的なSQLがないと言ったのは知っていますが、ストレートSQLでそれを行う方法がわかりません。

ピボットテーブルと列の連結 および SQL 2005のPIVOT で、同様の問題に対する私の回答を確認してください。

動的なSQLはインジェクションに対して脆弱ではなく、それを禁止する正当な理由はありません。別の可能性(データの変更頻度が非常に低い場合)は、コード生成を行うことです。動的なSQLの代わりに、SQLがストアドプロシージャに対して定期的に生成されます。

12
Cade Roux

動的SQLを使用してこのデータをPIVOTするには、SQL Server2005 +で次のコードを使用できます。

テーブルの作成:

CREATE TABLE yourtable
    ([StudentName] varchar(8), [AssignmentName] varchar(12), [Grade] int)
;

INSERT INTO yourtable
    ([StudentName], [AssignmentName], [Grade])
VALUES
    ('StudentA', 'Assignment 1', 100),
    ('StudentA', 'Assignment 2', 80),
    ('StudentA', 'Total', 180),
    ('StudentB', 'Assignment 1', 100),
    ('StudentB', 'Assignment 2', 80),
    ('StudentB', 'Assignment 3', 100),
    ('StudentB', 'Total', 280)
;

動的ピボット:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(AssignmentName) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT StudentName, ' + @cols + ' from 
             (
                select StudentName, AssignmentName, grade
                from yourtable
            ) x
            pivot 
            (
                min(grade)
                for assignmentname in (' + @cols + ')
            ) p '

execute(@query)

SQL Fiddle with Demo を参照してください

結果は次のとおりです。

| STUDENTNAME | ASSIGNMENT 1 | ASSIGNMENT 2 | ASSIGNMENT 3 | TOTAL |
--------------------------------------------------------------------
|    StudentA |          100 |           80 |       (null) |   180 |
|    StudentB |          100 |           80 |          100 |   280 |
8
Taryn

これを行うために私が見つけた唯一の方法は、動的SQLを使用して、列ラベルを変数に入れることです。

1
BoltBait

これは SQL 2005のPIVOT と同じです。

このデータがレポートで使用される場合は、SSRSマトリックスを使用できます。結果セットから動的に列を生成します。私はこれを何度も使用しました-動的クロス集計レポートには非常にうまく機能します。

これは動的SQLを使用した良い例です。 http://www.simple-talk.com/community/blogs/andras/archive/2007/09/14/37265.aspx

0
Booji Boy

information_schemaにクエリを実行して列名とタイプを取得し、結果セットを作成するときにその結果をサブクエリとして使用できます。ログインのアクセスを少し変更する必要がある可能性があることに注意してください。

0
tsilb