【问题标题】:How do i transform rows into columns in sql server 2005sql server 2005如何将行转换为列
【发布时间】:2010-02-26 20:25:55
【问题描述】:

stackoverflow 中有一个question,标题相同,但这不是我要找的。
我有一张像下面这样的桌子

Name   | Count  
----------------    
Chery  | 257  
Drew   | 1500
Morgon | 13  
Kath   | 500  
Kirk   | 200  
Matt   | 76 

我需要把这个结果集转换成这样的东西

Chery | Drew | Morgon | Kath | Kirk | Matt  
-------------------------------------------  
257     1500     13      500    200    76

如何使用 sql server 2005 实现这一点?

【问题讨论】:

    标签: sql sql-server sql-server-2005 pivot


    【解决方案1】:

    类似的问题here,here在stackoverflow中有回答。

    您需要在查询中使用运算符 PIVOT 来实现这一点。以下是有关如何执行此操作的示例和说明。该示例引用自 this 来源。

    ---I assumed your tablename as TESTTABLE---
    DECLARE @cols NVARCHAR(2000)
    DECLARE @query NVARCHAR(4000)
    
    SELECT  @cols = STUFF(( SELECT DISTINCT TOP 100 PERCENT
                                    '],[' + t.Name
                            FROM    TESTTABLE AS t
                            ORDER BY '],[' + t.Name
                            FOR XML PATH('')
                          ), 1, 2, '') + ']'
    
    SET @query = N'SELECT '+ @cols +' FROM
    (SELECT t1.Name , t1.Count FROM TESTTABLE AS t1) p
    PIVOT (MAX([Count]) FOR Name IN ( '+ @cols +' ))
    AS pvt;'
    
    EXECUTE(@query)
    

    说明

    1.查询的第一部分

    SELECT  @cols = STUFF(( SELECT DISTINCT TOP 100 PERCENT
                            '],[' + t.Name
                    FROM TESTTABLE AS t
                    ORDER BY '],[' + t.Name
                    FOR XML PATH('')
                  ), 1, 2, '') + ']'
    

    在单行中为您的 Name 列值提供一个很好的扁平化结果,如下所示

    [Cheryl],[Drew],[Karen],[Kath],[Kirk],[Matt]  
    

    您可以详细了解 STUFF 和 XML PATH herehere

    2.SELECT + @cols + FROM 将选择所有行作为最终结果集的列名(pvt - 步骤 3)

    Select [Chery],[Drew],[Morgan],[Kath],[Kirk],[Matt] 
    

    3.此查询提取我们创建交叉表结果所需的所有数据行。查询之后的 (p) 正在创建一个结果临时表,然后可以使用该表来满足第 1 步的查询。

    (SELECT t1.Name, t1.Count FROM  TESTTABLE AS t1) p
    

    4.PIVOT表达式

    PIVOT (MAX (Count) FOR Name IN ( @cols) AS pvt
    

    进行实际汇总并将结果放入名为 pvt as 的临时表中

    Chery | Drew | Morgon | Kath | Kirk | Matt  
    -------------------------------------------  
    257     1500     13      500    200    76
    

    【讨论】:

    • +1,很好的解决方案和答案。请注意,TOP 100 PERCENT 可以更改为TOP 30 或其他任何内容,因此如果您有很多行,则不要超过列数。
    【解决方案2】:

    Using PIVOT and UNPIVOT

    您可以使用PIVOTUNPIVOT 关系运算符改变一个 表值表达式到另一个 桌子。 PIVOT 旋转一个表值 通过转动独特的表达 中一列的值 表达式到多个列中 输出,并执行聚合 在任何地方都需要它们 剩余的列值是 想要在最终输出中。 UNPIVOT 执行相反的操作 通过旋转 a 的列进行 PIVOT 表值表达式到列 价值观。

    快速回答是

    SELECT Chery, Drew, Morgon, Kath, Kirk, Matt
    FROM 
    (SELECT [Name], [Count] From Foo)
    PIVOT
    (
       MIN([Count])
       FOR [Name] IN (Chery, Drew, Morgon, Kath, Kirk, Matt)
    ) AS PivotTable
    

    【讨论】:

      【解决方案3】:

      如果您想避免任何复杂的事情,例如枢轴或接受的答案,您可以这样做! (大部分代码只是设置测试数据以防万一有人想尝试)

      /* set up your test table */
      declare @TestData table (Name Varchar(80),[Count] int)    
      insert into @TestData (Name, [count])
      Select 'Chery' as name, 257 as [count]  
      union all select 'Drew', 1500
      union all select 'Morgon',13  
      union all select 'Kath', 500  
      union all select 'Kirk', 200  
      union all select 'Matt', 76 
      
      /* the query */
      Declare @Query Varchar(max)
      Select @Query=Coalesce(@query+', ','SELECT ') +Convert(VarChar(5),[count]) +' as ['+name+']'
      from @TestData
      Execute (@Query)
      /* result 
      
      Chery       Drew        Morgon      Kath        Kirk        Matt
      ----------- ----------- ----------- ----------- ----------- -----------
      257         1500        13          500         200         76
      
      */
      

      【讨论】:

        猜你喜欢
        • 2012-03-19
        • 2012-08-04
        • 1970-01-01
        • 2018-12-22
        • 2011-08-18
        • 2019-07-16
        • 2015-12-04
        • 2011-12-22
        • 1970-01-01
        相关资源
        最近更新 更多