我在下面的表格中有一些数据。
CREATE TABLE #NetProfit (ID int, [Name] varchar(50),[Class] varchar(50), Balance money)
go
--Populate Sample records
INSERT INTO #NetProfit VALUES(4,'Income','No Class',303386.8462)
INSERT INTO #NetProfit VALUES(6,'Expenses','No Class',22443.5317)
INSERT INTO #NetProfit VALUES(4,'Income','2 TestUser3',0.00)
INSERT INTO #NetProfit VALUES(5,'Cost','2 TestUser3',0.3875)
INSERT INTO #NetProfit VALUES(6,'Expenses','2 TestUser3',6439.2129)
INSERT INTO #NetProfit VALUES(5,'Cost','3 TestUser3',0.1395)
INSERT INTO #NetProfit VALUES(6,'Expenses','3 TestUser3',6451.6129)
INSERT INTO #NetProfit VALUES(5,'Cost','38 Code#1012',3.0225)
INSERT INTO #NetProfit VALUES(6,'Expenses','38 Code#1012',30.225)
go
select * from #NetProfit
drop table #NetProfit
+----+----------+--------------+-------------+
| ID | Name | Class | Balance |
+----+----------+--------------+-------------+
| 4 | Income | No Class | 303386.8462 |
| 6 | Expenses | No Class | 22443.5317 |
| 4 | Income | 2 TestUser3 | 0 |
| 5 | Cost | 2 TestUser3 | 0.3875 |
| 6 | Expenses | 2 TestUser3 | 6439.2129 |
| 5 | Cost | 3 TestUser3 | 0.1395 |
| 6 | Expenses | 3 TestUser3 | 6451.6129 |
| 5 | Cost | 38 Code#1012 | 3.0225 |
| 6 | Expenses | 38 Code#1012 | 30.225 |
+----+----------+--------------+-------------+
我想通过[Class]列减去[Balance]列行方式组。 对于前者每个[类]列的NetProfit =(收入 - 成本 - 费用),按[类别]分组。
这是我期待的输出。
+-------------+-------------+-------------+--------------+
| No Class | 2 TestUser3 | 3 TestUser3 | 38 Code#1012 |
+-------------+-------------+-------------+--------------+
| 280943.3145 | 6439.6004 | 6451.7524 | 33.2475 |
+-------------+-------------+-------------+--------------+
任何帮助将不胜感激。谢谢!
答案 0 :(得分:0)
这可能是实现预期结果的第一步:
SELECT NP.Class, ABS(ISNULL(SUM(CASE NP.Name WHEN 'Income' THEN NP.Balance END), 0) - SUM(CASE NP.Name WHEN 'Income' THEN NULL ELSE NP.Balance END)) AS Balance
FROM #NetProfit AS NP
GROUP BY NP.Class;
然后你必须动态调整这些结果。静态地,您的查询应该如下所示:
SELECT *
FROM (
SELECT NP.Class, ABS(ISNULL(SUM(CASE NP.Name WHEN 'Income' THEN NP.Balance END), 0) - SUM(CASE NP.Name WHEN 'Income' THEN NULL ELSE NP.Balance END)) AS Balance
FROM #NetProfit AS NP
GROUP BY NP.Class) AS SourceTable
PIVOT (MAX(Balance) FOR Class IN ([2 TestUser3], [3 TestUser3], [38 Code#1012], [No Class])) AS PivotTable;
因此,通过插入动态SQL,结果如下:
DECLARE @SQL NVARCHAR(MAX);
DECLARE @Col NVARCHAR(MAX);
SET @Col = STUFF(( SELECT DISTINCT ',' + QUOTENAME(NP.Class)
FROM #NetProfit AS NP
FOR XML PATH('')), 1, 1, '');
SET @SQL = N'
SELECT *
FROM (
SELECT NP.Class, ABS(ISNULL(SUM(CASE NP.Name WHEN ''Income'' THEN NP.Balance END), 0) - SUM(CASE NP.Name WHEN ''Income'' THEN NULL ELSE NP.Balance END)) AS Balance
FROM #NetProfit AS NP
GROUP BY NP.Class) AS SourceTable
PIVOT (MAX(Balance) FOR Class IN (' + @Col + N')) AS PivotTable';
EXECUTE sys.sp_executesql @SQL;
输出结果:
+-------------+-------------+--------------+-------------+
| 2 TestUser3 | 3 TestUser3 | 38 Code#1012 | No Class |
+-------------+-------------+--------------+-------------+
| 6439,6004 | 6451,7524 | 33,2475 | 280943,3145 |
+-------------+-------------+--------------+-------------+
答案 1 :(得分:0)
此查询以行的形式返回计算。 使用数据透视表,您可以将行转换为列
select isnull(c1, c2), isnull(i, 0)-isnull(e,0) from (
select * from
(select class c1, sum(balance) i
from #NetProfit
where Name = 'income'
group by class) i
full join
(
select class c2, sum(balance) e
from #NetProfit
where Name != 'income'
group by class) e on i.c1 = e.c2) t
答案 2 :(得分:-1)
试试这个(假设ID为4,收入为正,而其余则应视为否定;
select
[Class No]=SUM(case when [Class]='No Class' then (case when ID=4 then Balance else Balance*-1 end) else 0 end),
[TestUser2]=SUM(case when [Class]='2 TestUser3' then (case when ID=4 then Balance else Balance*-1 end) else 0 end),
[TestUser3]=SUM(case when [Class]='3 TestUser3' then (case when ID=4 then Balance else Balance*-1 end) else 0 end),
[Code#1012]=SUM(case when [Class]='Code#1012' then (case when ID=4 then Balance else Balance*-1 end) else 0 end)
from
#NetProfit