我上次使用mysql发布了类似的问题。但是这次我想使用SQL服务器获取总数量值。我也发布了我的代码。请检查
DB Schema ===
CREATE DATABASE test;
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
我仍然无法获得总数。
答案 0 :(得分:1)
下面的代码罚款。我创建了一个临时表,你可以用它替换它 你的桌名;
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
答案 1 :(得分:0)
我会形成我的查询,看起来像这样。
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)
变量用于构建SUM(CASE)
以及将通过调用EXEC(@SQL)
执行的SQL
答案 2 :(得分:0)
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