4

テーブル データをより視覚的に魅力的な出力形式に操作する方法を理解しようとしています。私が望むものは別のレポートソフトウェアを対象としている可能性があるため、これは問題の一部である可能性があります。

私はこのようなテーブルを持っています

teacher    student
----------------------
teacher1   Bob
teacher1   Jim
teacher2   Sam
teacher3   Bill
teacher3   John
teacher3   Eric

次のようなテーブルが必要です。

teacher1    teacher2    teacher3
---------------------------------
Bob         Sam          Bill
Jim         null         John
null        null         Eric

そこで、すべての教師の名前を変数に詰め込んでから a を使用しようとしましたPivotが、集計を選択する必要があるため、次のようにMaxorMin学生しか取得できません。

DECLARE @teacherList AS VARCHAR(max)

SELECT @teacherList = Stuff((SELECT DISTINCT',[' + teacher + ']'
                              FROM myTable
                              FOR xml path('')), 1, 1, '')

DECLARE @dynamic_pivot_query AS VARCHAR(max)

SET @dynamic_pivot_query = 'select' + @teacherList + 
'from 
(
    SELECT [teacher],[student]
    FROM [dbo].[myTable]
) as S
Pivot
(
    MIN([student])
    FOR teacher IN (' + @teacherList + ')
) as P
'
EXEC(@dynamic_pivot_query)  

この結果は次のとおりです。

teacher1    teacher2    teacher3
---------------------------------
Bob         Sam          Bill

以下を仮定します。

  1. 教師の数とその名前は不明です(可変)
  2. 教師ごとの生徒数は不明であり、教師ごとに異なる可能性があります

これを行う方法はありますか?

4

2 に答える 2

2

いいえ。

SQL Server には静的型付けが必要です。動的な数の列または動的な列の型を作成する方法はありません (sql_variant を除く)。

したがって、動的 SQL ソリューションが唯一の可能な選択肢です。

最小/最大で混乱しないでください: 集計ごとに正確に 0 または 1 項目が常に存在します。構文は理論的な正確さのために集計を必要としますが、(教師、学生) が一意である場合、集計は何もしません。害はなく、結果も変わりません。

アプローチはそのままです。実際、私は今この瞬間に同じタイプのコードに取り組んでいます (これは面白いです)。

于 2012-04-23T17:54:34.100 に答える
1

を使用row_numberして、必要な結果を得ることができます。

SET @dynamic_pivot_query = 'select ' + @teacherList + 
'from 
(
    SELECT [teacher],[student], row_number() over(partition by teacher order by student) as rn
    FROM [dbo].[myTable]
) as S
Pivot
(
    MIN([student])
    FOR teacher IN (' + @teacherList + ')
) as P
'

更新:
SQL インジェクションの脆弱性を取り除くにはquotename、フィールド リストを適切に引用するために使用する必要があります。

SELECT @teacherList = Stuff((SELECT DISTINCT',' + quotename(teacher)
                              FROM myTable
                              FOR xml path('')), 1, 1, '') 
于 2012-04-23T18:27:56.537 に答える