SQL Server 2012中包含列和行总计的动态数据透视表

时间:2017-01-12 09:47:05

标签: sql-server

我有表RPT_DailySalesSummary,列CalDate,OrderID,SalesAmount,LocRecID。

CalDate    OrderID SalesAmount  LocRecID
2016-12-01 R101    100          81
2016-12-01 R102    120          81
2016-12-01 R113    150          82
2016-12-01 R104    130          85
2016-12-02 R205    250          81
2016-12-02 R106    104          82
2016-12-02 R112    80           85
2016-12-02 R032    80           85

我想在结果表下面输出每个日历日期的位置ID。 (注意:地点的数量是动态的)

CalDate      81    82    85    Total
2016-12-01   220   150   130   500
2016-12-02   250   104   160   514
Total        470   254   290   1014

我在下面写的代码可以输出数据透视表但没有行和列总数。

DECLARE @cols       NVARCHAR(MAX)=''
DECLARE @query      NVARCHAR(MAX)=''

SELECT @cols = @cols + QUOTENAME(LocRecID) + ',' 
FROM (SELECT DISTINCT LocRecID FROM dbo.RPT_DailySalesSummary ) AS tmp
SELECT @cols = SUBSTRING(@cols, 0, LEN(@cols))


SET @query = 
            'SELECT * FROM 
            (
                    SELECT CalDate, SalesAmount, LocRecID 
                    FROM dbo.RPT_DailySalesSummary
            ) src
            PIVOT 
            (
                    SUM(SalesAmount) FOR LocRecID IN (' + @cols + ')
            ) piv'

execute(@query)

我感到很难并且不明白如何使用PIVOT。我不知道如何继续创建我期望的结果代码。

任何人都可以提供帮助?非常感谢。

1 个答案:

答案 0 :(得分:0)

试试这个

您问题中的架构:

CREATE TABLE #RPT_DailySalesSummary (
    CalDate DATE
    ,OrderID VARCHAR(10)
    ,SalesAmount INT
    ,LocRecID INT
    )

INSERT INTO #RPT_DailySalesSummary
SELECT '2016-12-01', 'R101',    100,          81
UNION ALL
SELECT '2016-12-01', 'R102',    120,          81
UNION ALL
SELECT '2016-12-01', 'R113',    150,          82
UNION ALL
SELECT '2016-12-01', 'R104',    130 ,         85
UNION ALL
SELECT '2016-12-02', 'R205',    250 ,         81
UNION ALL
SELECT '2016-12-02', 'R106',    104,          82
UNION ALL
SELECT '2016-12-02', 'R112',    80 ,          85
UNION ALL
SELECT '2016-12-02', 'R032',    80 ,          85

您需要像准备列列表

一样准备列的SUM
DECLARE @cols       NVARCHAR(MAX)=''
DECLARE @query      NVARCHAR(MAX)=''
DECLARE @COLS_SUM   NVARCHAR(MAX)=''
DECLARE @COLS_TOT   NVARCHAR(MAX)=''

--Preparing columns for Pivot
SELECT @cols = @cols + QUOTENAME(LocRecID) + ',' 
FROM (SELECT DISTINCT LocRecID FROM #RPT_DailySalesSummary ) AS tmp
SELECT @cols = SUBSTRING(@cols, 0, LEN(@cols))

--Preparing sum of columns for Totals Horizontal
SELECT @COLS_SUM = @COLS_SUM + QUOTENAME(LocRecID) + '+' 
FROM (SELECT DISTINCT LocRecID FROM #RPT_DailySalesSummary ) AS tmp
SELECT @COLS_SUM = ','+ SUBSTRING(@COLS_SUM, 0, LEN(@COLS_SUM)) +' AS TOTAL'

--Preparing sum of individual columns for Totals Vertically
SELECT @COLS_TOT = @COLS_TOT +'SUM('+ QUOTENAME(LocRecID) + '),' 
FROM (SELECT DISTINCT LocRecID FROM #RPT_DailySalesSummary ) AS tmp
SELECT @COLS_TOT = SUBSTRING(@COLS_TOT, 0, LEN(@COLS_TOT)) 



SET @query = 
            'SELECT *'+@COLS_SUM+'  INTO #TAB FROM 
            (
                    SELECT CalDate, SalesAmount, LocRecID 
                    FROM #RPT_DailySalesSummary
            ) src
            PIVOT 
            (
                    SUM(SalesAmount) FOR LocRecID IN (' + @cols + ')
            ) piv

            SELECT * FROM #TAB
            UNION ALL
            SELECT NULL AS TOTAL ,'+@COLS_TOT+',SUM(TOTAL) FROM #TAB

            '

execute(@query)

结果将是

╔════════════╦═════╦═════╦═════╦═══════╗
║  CalDate   ║ 81  ║ 82  ║ 85  ║ TOTAL ║
╠════════════╬═════╬═════╬═════╬═══════╣
║ 2016-12-01 ║ 220 ║ 150 ║ 130 ║   500 ║
║ 2016-12-02 ║ 250 ║ 104 ║ 160 ║   514 ║
║ NULL       ║ 470 ║ 254 ║ 290 ║  1014 ║
╚════════════╩═════╩═════╩═════╩═══════╝