SQL Server Pivots:将行值显示到列标题

时间:2012-03-06 13:57:55

标签: sql-server tsql

我有一个表格(项目),格式如下:

ITEMNO | WEEKNO | VALUE  
A1234  |   1    |  805  
A2345  |   2    |  14.50  
A3547  |   2    |  1396.70  
A2208  |   1    |  17.65  
A4326  |   6    |  19.99

这是一张表格,显示给定周内物品的销售价值。

结果或我想以表格格式显示的是一行中的项目编号,后面是包含值的每周的列,例如

ITEMNO | WK1 | WK2 | WK3 | WK4 | WK5  ...etc up to 52  
A1234  | 805 | 345 | 234 | 12  | 10   ...etc up to 52  
A2345  |  23 | 12  | 456 | 34  | 99   ...etc up to 52  
A3456  | 234 | 123 | 34  | 25  | 190  ...etc up to 52  

虽然我已经52岁......所以我只有9周的数据,但这会随着时间的推移而增加。

所以基本上我要显示的是将周数值作为列标题。

这可能吗......虽然我很想通过代码/(asp.net)抓取数据并正确显示但是我想知道是否有在SQL中显示它的情况?

有人知道或认为这可能是最好的方法吗?

5 个答案:

答案 0 :(得分:8)

使用静态SQL和动态SQL有两种方法:

静态数据透视:

SELECT P.ItemNo, IsNull(P.[1], 0) as Wk1, IsNull(P.[2], 0) as Wk2
    , IsNull(P.[3], 0) as Wk3, IsNull(P.[4], 0) as Wk4
    , IsNull(P.[5], 0) as Wk5, IsNull(P.[6], 0) as Wk6
    , IsNull(P.[7], 0) as Wk7, IsNull(P.[8], 0) as Wk8
    , IsNull(P.[9], 0) as Wk9
FROM
(
    SELECT ItemNo, WeekNo, [Value]
    FROM dbo.Items
) I
PIVOT
(
    SUM([Value])
    FOR WeekNo IN ([1], [2], [3], [4], [5], [6], [7], [8], [9])
) as P

动态数据透视:

DECLARE
@cols AS NVARCHAR(MAX),
@y    AS INT,
@sql  AS NVARCHAR(MAX);

-- Construct the column list for the IN clause
SET @cols = STUFF(
(SELECT N',' + QUOTENAME(w) AS [text()]
FROM (SELECT DISTINCT WeekNo AS W FROM dbo.Items) AS W
ORDER BY W
FOR XML PATH('')),
1, 1, N'');


-- Construct the full T-SQL statement
-- and execute dynamically
SET @sql = N'SELECT *
            FROM (SELECT ItemNo, WeekNo, Value
                    FROM dbo.Items) AS I
            PIVOT(SUM(Value) FOR WeekNo IN(' + @cols + N')) AS P;';

EXEC sp_executesql @sql;
GO

答案 1 :(得分:3)

也许是这样的:

测试数据

CREATE TABLE #tbl 
    (
        ITEMNO VARCHAR(100),
        WEEKNO INT, 
        VALUE FLOAT
    )

INSERT INTO #tbl
VALUES
    ('A1234',1,805),
    ('A2345',2,14.50),  
    ('A3547',2,1396.70),  
    ('A2208',1,17.65),
    ('A4326',6,19.99)

周列

DECLARE @cols VARCHAR(MAX)

;WITH Nbrs ( n ) AS (
        SELECT 1 UNION ALL
        SELECT 1 + n FROM Nbrs WHERE n < 52 )
SELECT @cols = COALESCE(@cols + ','+QUOTENAME('WK'+CAST(n AS VARCHAR(2))),
                     QUOTENAME('WK'+CAST(n AS VARCHAR(2))))
FROM
    Nbrs

仅包含周数

DECLARE @cols VARCHAR(MAX)
;WITH CTE
AS
(
    SELECT
        ROW_NUMBER() OVER(PARTITION BY WEEKNO ORDER BY WEEKNO) AS RowNbr,
        WEEKNO
    FROM
        #tbl
)
SELECT @cols = COALESCE(@cols + ','+QUOTENAME('WK'+CAST(WEEKNO AS VARCHAR(2))),
                     QUOTENAME('WK'+CAST(WEEKNO AS VARCHAR(2))))
FROM
    CTE
WHERE
    CTE.RowNbr=1

动态支点

DECLARE @query NVARCHAR(4000)=
N'SELECT
    *
FROM
(
    SELECT
        tbl.ITEMNO,
        ''WK''+CAST(tbl.WEEKNO AS VARCHAR(2)) AS WEEKNO,
        tbl.VALUE
    FROM
        #tbl as tbl
) AS p
PIVOT
(
    SUM(VALUE)
    FOR WEEKNO IN ('+@cols+')
) AS pvt'
EXECUTE(@query)

删除临时表

DROP TABLE #tbl

答案 2 :(得分:1)

使用Pivot,虽然代码很多.. 如果您在报告服务中创建报告,可以使用矩阵..

答案 3 :(得分:1)

按照以下演练清楚解释

http://www.tsqltutorials.com/pivot.php

答案 4 :(得分:1)

如果要直接在sql中执行此操作,可以使用PIVOT

使用SQL Server执行此操作比使用客户端更高效,具体取决于数据的大小和聚合。