【问题标题】:Using PIVOT in SQL Server 2008在 SQL Server 2008 中使用 PIVOT
【发布时间】:2023-03-13 06:40:01
【问题描述】:

假设我有一些数据,在 SQL Server 2008 表或 [table] 类型的变量中:

author_id     review_id     question_id     answer_id
88540         99001         1               719
88540         99001         2               720
88540         99001         3               721
88540         99001         4               722
88540         99001         5               723
36414         24336         1               302
36414         24336         2               303
36414         24336         3               304
36414         24336         4               305
36414         24336         5               306

我想将数据检索为如下所示的结果集:

author_id     review_id     1     2     3     4     5
88540         99001         719   720   721   722   723
36414         24336         302   303   304   305   306

我怀疑 PIVOT 运算符是我需要的(无论如何,根据this post),但我不知道如何开始,尤其是当 question_id 行数表可以变化。在上面的示例中,它是 5,但在另一个查询中,该表可能会填充 7 个不同的问题。

【问题讨论】:

    标签: sql sql-server tsql sql-server-2008 pivot


    【解决方案1】:

    实际上,您最好在客户端中执行此操作。假设您正在使用 Reporting Services,根据您的第一个结果集获取数据并使用矩阵显示它,其中 author_id 和 review_id 在行组中,question_id 在列组中,MAX(answer_id) 在中间。

    查询是可行的,但您现在需要动态 SQL。

    ...类似:

    DECLARE @QuestionList nvarchar(max);
    SELECT @QuestionList = STUFF(
    (SELECT ', ' + quotename(question_id)
    FROM YourTable
    GROUP BY question_id
    ORDER BY question_id
    FOR XML PATH(''))
    , 1, 2, '');
    
    DECLARE @qry nvarchar(max);
    SET @qry = '
    SELECT author_id, review_id, ' + @QuestionList + 
    FROM (SELECT author_id, review_id, question_id, answer_id
          FROM YourTable
         ) 
    PIVOT
    (MAX(AnswerID) FOR question_id IN (' + @QuestionList + ')) pvt
    ORDER BY author_id, review_id;';
    
    exec sp_executesql @qry;
    

    【讨论】:

    • 这似乎是我需要的。我会试一试并报告——谢谢!
    • 请记住子查询。如果您只使用“SELECT * FROM YourTable”,那么所涉及的任何其他列都会影响 PIVOT 函数提供的隐式分组。如果您有任何错误,请注释掉 exec 行,将其替换为 select @qry
    • 我不再使用 [SELECT *] ——我总是明确说明我访问的列——所以这不会成为问题。是的,我使用 [select @qry] 有一段时间了,这样我就可以在生成 SQL 语句运行之前查看/调试它。您的代码按承诺运行 - 非常感谢您的帮助!
    【解决方案2】:

    Here你有很好的例子和解释。

    你的情况是这样的:

    SELECT author_id, review_id, [1], [2], [3], [4], [5]
    FROM 
        (
            SELECT author_id, review_id, question_id, answer_id
            FROM the_table
        ) up
    PIVOT (MAX(answer_id) FOR question_id IN ([1],[2],[3],[4],[5])) AS pvt
    

    【讨论】:

      【解决方案3】:
      SELECT author_id, review_id, [1], [2], [3], [4], [5]
      FROM 
          (
              SELECT author_id, review_id, question_id, answer_id
              FROM the_table
          ) up
      PIVOT (MAX(answer_id) FOR
      

      【讨论】:

        【解决方案4】:
        select * 
        from @t pivot
        (
            max(answer_id) for question_id in ([1],[2],[3],[4],[5])
        ) pivotT
        

        改变列表([1]、[2]、[3]、[4]、[5])的唯一方法是在字符串中(动态)构建此查询,然后执行它。

        【讨论】:

          【解决方案5】:

          this answer

          基本上,您预先检查数据以获取列,然后使用动态数据透视表动态生成 SQL。真的没有非动态的方式,因为你要返回的集合中列的定义是不固定的。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-10-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-20
            • 1970-01-01
            相关资源
            最近更新 更多