如何转置/透视 SQL 表

Posted

技术标签:

【中文标题】如何转置/透视 SQL 表【英文标题】:How to transpose/pivot SQL table 【发布时间】:2014-04-09 06:24:08 【问题描述】:

我有一个如下的 SQL 表:

ID    StepID   Rating   Comments     StaffID    Date
-------------------------------------------------------------
1     1        6          blah blah     1025      2014-03-20 
1     2        6          blah blah     1025      2014-03-20 
1     3        8          blah blah     1025      2014-03-20 
1     4        7          blah blah     1025      2014-03-20 

如您所见,ID、Comments、StaffID 和 Dates 列的数据重复(相同)。

如何将上表变成如下图:

ID    Step1   Step2  Step3  Step4  Comments     StaffID    Date
----------------------------------------------------------------------------------
1      6       6      8      7    blah blah     1025    2014-03-20 

任何帮助表示赞赏!

【问题讨论】:

步数总是1到4吗? 【参考方案1】:

你可以这样做:

测试数据

DECLARE @tbl TABLE(ID INT,StepID int,Rating INT, 
                   Comments VARCHAR(200), StaffID INT,Date DATETIME)

INSERT INTO @tbl
VALUES
(1,1,6,'blah blah',1025,'2014-03-20'),
(1,2,6,'blah blah',1025,'2014-03-20'),
(1,3,8,'blah blah',1025,'2014-03-20'),
(1,4,7,'blah blah',1025,'2014-03-20')

查询

SELECT
    pvt.ID,
    pvt.[1] AS Step1,
    pvt.[2] AS Step2,
    pvt.[3] AS Step3,
    pvt.[4] AS Step4,
    pvt.Comments,
    pvt.StaffID,
    pvt.Date
FROM
(
    SELECT 
        * 
    FROM 
        @tbl AS tbl
) AS sourceTable
PIVOT
(
    MAX(Rating)
    FOR StepID IN ([1],[2],[3],[4])
) AS pvt

编辑

如果你不知道你有多少步。你需要做一个动态的支点。像这样:

测试数据

CREATE TABLE tbl
(
    ID INT,
    StepID int,
    Rating INT, 
    Comments VARCHAR(200), 
    StaffID INT,
    Date DATETIME
)

INSERT INTO tbl
VALUES
(1,1,6,'blah blah',1025,'2014-03-20'),
(1,2,6,'blah blah',1025,'2014-03-20'),
(1,3,8,'blah blah',1025,'2014-03-20'),
(1,4,7,'blah blah',1025,'2014-03-20')

获取独特的步骤:

DECLARE @cols VARCHAR(MAX)
SELECT @cols=STUFF
(
    (
        SELECT DISTINCT
            ',' +QUOTENAME('Step'+CAST(tbl.StepID AS VARCHAR(100)))
        FROM
            tbl
        FOR XML PATH('')
    )
,1,1,'')

执行动态枢轴:

DECLARE @query NVARCHAR(4000)=
'SELECT
    *
FROM
(
    SELECT 
        tbl.Comments,
        tbl.Date,
        tbl.ID,
        tbl.Rating,
        tbl.StaffID,
        ''Step''+CAST(tbl.StepID AS VARCHAR(100)) AS StepID
    FROM 
        tbl
) AS sourceTable
PIVOT
(
    MAX(Rating)
    FOR StepID IN ('+@cols+')
) AS pvt
 DROP TABLE tbl'

 EXECUTE(@query)

在我的情况下,删除表:

DROP TABLE tbl

【讨论】:

是否必须指定[1],[2],[3],[4]?因为 stepID 可能并不总是这些值?我该如何解决这个问题? @viv_acious :更新了答案 非常感谢您的超快速响应 - 我现在就去看看 :) thx thx! 没问题。很高兴为您提供帮助

以上是关于如何转置/透视 SQL 表的主要内容,如果未能解决你的问题,请参考以下文章

一道SQL面试题——表行列数据转换(表转置)

如何在不使用数据透视的情况下将行转换或转置为 SQL 中的列?

使用数据透视/转置的 SQL Server

SQL Server 转置数据 - 可能进行数据透视?

关于sql 表 转置 相关的请教!

转置列或反透视 SQL 查询