SQL 服务器的数据透视总数

Pivot total with SQL Server

我上次使用 mysql 发布了类似的问题。但是这次我想使用 SQL 服务器获得总的枢轴值。我也在发布我的代码。请检查

数据库模式===

创建数据库测试;

CREATE TABLE [dbo].[RAccounts_Receivable](
    [id] [int] NOT NULL,
    [trntypename] [nvarchar](max) NULL,
    [datecreated] [date] NULL,
    [AmountDue] [decimal](18, 0) NULL) ;

INSERT INTO [dbo].[RAccounts_Receivable] 
(id, trntypename,datecreated,AmountDue )
VALUES
(1, 'Pay Bills', '2016-01-02', 50),
(2, 'Pay Bills', '2016-01-10', 60),
(3, 'Sales Returns', '2016-01-20', 30),
(4, 'Sales Returns', '2016-01-15', 20),
(5, 'Pay Bills', '2016-02-15', 10),


(6, 'Sales Returns', '2016-02-20', 20),
(7, 'Sales Returns', '2016-02-15', 10)

到目前为止的代码

SELECT * FROM 
            (SELECT FORMAT(datecreated,'yyyyMM') AS date
            ,SUM(AmountDue) AS AmountDue
            ,trntypename
    FROM RAccounts_Receivable
    WHERE 
            (trntypename='Pay Bills' OR trntypename='Sales Return')
            AND datecreated >= DATEADD(month, DATEDIFF(month, 0, GETDATE())-7, 0) 
            GROUP By [trntypename],FORMAT(datecreated,'yyyyMM')) AS Basedata 

PIVOT
(
  SUM(AmountDue) FOR date IN ([201601],[201602])
) AS p 

到目前为止的结果

trntypename | 201601 | 201602

Pay Bills   | 110    | 10
Sales Return| 50     | 30  

预期结果

trntypename | 201601 | 201602 | total

Pay Bills   | 110    | 10     | 120 
Sales Return| 50     | 30     | 80
total       | 160    | 40     | 200 

我还是无法得到总数。

下面的代码可以正常工作。我创建了一个临时 table 你可以用 你的 table 名字;

WITH CodeSoFar AS(
SELECT * FROM 
        (SELECT CONVERT(nvarchar(6), datecreated,112) AS date
         ,SUM(AmountDue) AS AmountDue
         ,trntypename
         FROM ##RAccounts_Receivable

WHERE   (trntypename='Pay Bills' OR trntypename='Sales Returns')
        AND datecreated >= DATEADD(month, DATEDIFF(month, 0, GETDATE())-7, 0) 
         GROUP By [trntypename],CONVERT(nvarchar(6), datecreated,112)
        ) AS ABC

 PIVOT
 (
   SUM(AmountDue) FOR date IN ([201601],[201602])
 ) AS p
 )
 SELECT *,[201601]+[201602] AS Total FROM  CodeSoFar
 UNION
 SELECT 'Total' AS Total,SUM([201601]) AS '201601',SUM([201602]) AS  '201602',Sum([201601]+[201602])
 FROM  CodeSoFar

我会形成我的查询看起来像这样。

SELECT  CASE WHEN GROUPING(trntypename) = 1 THEN 'Total' ELSE trntypename END AS trntypename,
        SUM(CASE WHEN FORMAT(datecreated,'yyyyMM') = '201601' THEN AmountDue END) AS [201601],
        SUM(CASE WHEN FORMAT(datecreated,'yyyyMM') = '201602' THEN AmountDue END) AS [201602],
        SUM(AmountDue) Total
FROM    RAccounts_Receivable
WHERE   (trntypename = 'Pay Bills'
         OR trntypename = 'Sales Returns')
        AND datecreated >= DATEADD(month,DATEDIFF(month,0,GETDATE()) - 7,0)
GROUP BY ROLLUP([trntypename])
ORDER BY CASE WHEN GROUPING(trntypename) = 1 THEN '1' ELSE 0 END

总计线使用ROLLUP()创建,其他总计使用SUM(CASE)

创建

为了动态生成这个。你可以使用这样的东西。

DECLARE @CaseQuery NVARCHAR(MAX) = 'SUM(CASE WHEN FORMAT(datecreated,''yyyyMM'') = ''<<dateval>>'' THEN AmountDue END) AS [<<dateval>>]',
        @SelectQuery NVARCHAR(MAX),
        @Sql NVARCHAR(MAX)

SELECT  @SelectQuery = COALESCE(@SelectQuery + ',', '') + REPLACE(@CaseQuery, '<<dateval>>', FORMAT(datecreated,'yyyyMM'))
FROM    [dbo].[RAccounts_Receivable]
WHERE   datecreated >= DATEADD(month,DATEDIFF(month,0,GETDATE()) - 7,0)
GROUP BY FORMAT(datecreated,'yyyyMM')
ORDER BY FORMAT(datecreated,'yyyyMM')

SET     @Sql = '
    SELECT  CASE WHEN GROUPING(trntypename) = 1 THEN ''Total'' ELSE trntypename END AS trntypename, ' + 
            @SelectQuery + ',
            SUM(AmountDue) Total
    FROM    RAccounts_Receivable
    WHERE   (trntypename = ''Pay Bills''
             OR trntypename = ''Sales Returns'')
            AND datecreated >= DATEADD(month,DATEDIFF(month,0,GETDATE()) - 7,0)
    GROUP BY ROLLUP([trntypename])
    ORDER BY CASE WHEN GROUPING(trntypename) = 1 THEN 1 ELSE 0 END
'
EXEC    (@Sql)

变量用于构建将通过调用EXEC(@SQL)

执行的SUM(CASE)和SQL
SELECT * FROM 
            (SELECT FORMAT(datecreated,'yyyyMM') AS date
            ,SUM(AmountDue) AS AmountDue
            ,trntypename
    FROM RAccounts_Receivable
    WHERE 
            (trntypename='Pay Bills' OR trntypename='Sales Return')
            AND datecreated >= DATEADD(month, DATEDIFF(month, 0, GETDATE())-7, 0) 
            GROUP By [trntypename],FORMAT(datecreated,'yyyyMM')) AS Basedata 

PIVOT
(
  SUM(AmountDue) FOR date IN ([201601],[201602])
) AS p

union 

SELECT 'total',sum([201601]) as '201601',sum([201602]) as '201602' FROM 
            (SELECT FORMAT(datecreated,'yyyyMM') AS dt
            ,SUM(AmountDue) AS [AmountDue]
            ,trntypename
    FROM RAccounts_Receivable
    WHERE 
            (trntypename='Pay Bills' OR trntypename='Sales Return')
            AND datecreated >= DATEADD(month, DATEDIFF(month, 0, GETDATE())-7, 0) 
            GROUP By [trntypename],FORMAT(datecreated,'yyyyMM')) AS Basedata 

PIVOT
(
  SUM(AmountDue) FOR dt IN ([201601],[201602])
) AS p