SQL SUM计算

时间:2011-04-14 20:53:18

标签: sql sql-server sql-server-2008 sum

我编写了以下查询来计算总和。怎么还可以让这个查询显示它总结的每个单独的记录?

SELECT 'BEN' + CardCode, SUM(PayAmount) 
FROM BENSALEM.dbo.PWZ3
INNER JOIN BENSALEM.dbo.OPWZ T5 ON T5.IdNumber = IdEntry
WHERE T5.PmntDate = '4/1/2011' 
AND T5.Canceled = 'N' 
AND Checked = 'Y'
GROUP BY CardCode

4 个答案:

答案 0 :(得分:3)

您希望在SELECT语句中使用WITH ROLLUP子句。根据您使用的SQL服务器类型,有一些不同的语法。

MS SQL Server 2000/2005将如下所示:

SELECT 'BEN' + CardCode, SUM(PayAmount) 
FROM BENSALEM.dbo.PWZ3
INNER JOIN BENSALEM.dbo.OPWZ T5 ON T5.IdNumber = IdEntry
WHERE T5.PmntDate = '4/1/2011' AND T5.Canceled = 'N' AND Checked = 'Y'
GROUP BY CardCode WITH ROLLUP

这将返回单个记录,以及第一个字段为NULL且第二个字段为SUM()的附加记录。请注意,您可以使用更多级别的分组执行此操作,并且它还将包括子总计以及将相应字段设置为NULL。

SQL Server 2008具有更符合ANSI标准的语法,可以执行相同的操作:

SELECT 'BEN' + CardCode, SUM(PayAmount) 
FROM BENSALEM.dbo.PWZ3
INNER JOIN BENSALEM.dbo.OPWZ T5 ON T5.IdNumber = IdEntry
WHERE T5.PmntDate = '4/1/2011' AND T5.Canceled = 'N' AND Checked = 'Y'
GROUP BY ROLLUP(CardCode)

根据我的记忆,MySQL使用第一种形式,Oracle使用第二种形式。

编辑:

我的查询实际上并没有给出您想要的结果; ROLLUP()通过获取现有的聚合函数并在更广泛和更广泛的组上递归执行它来工作。你想要的是拥有一系列没有聚合函数的行,并应用聚合一次。

您可以使用COMPUTE BY子句获得此效果,但很久以前就已弃用,结果很混乱,所以我会避免使用它们。 (如果您确实需要,请查看MSDN以获取详细信息。)

实现目标的最简单方法是找到一种方法,使每条记录都是唯一的,例如包括主键字段,以便PayAmount和SUM(PayAmount)产生相同的结果,然后进行汇总。

SELECT IdEntry, 'BEN' + CardCode, SUM(PayAmount) 
FROM BENSALEM.dbo.PWZ3
INNER JOIN BENSALEM.dbo.OPWZ T5 ON T5.IdNumber = IdEntry
WHERE T5.PmntDate = '4/1/2011' AND T5.Canceled = 'N' AND Checked = 'Y'
GROUP BY ROLLUP(CardCode, IdEntry)

这会给你一个看起来像这样的结果:

1     BEN1234  1000
2     BEN1234  2000
3     BEN1234  1000
NULL  BEN1234  4000
4     BEN4567  1500
5     BEN4567  1500
6     BEN4567  1000
NULL  BEN4567  4000
NULL  NULL     8000

如果这对你有用,请告诉我们。

答案 1 :(得分:1)

您无法在同一查询中聚合和聚合,但可以将两者合并:

SELECT 'BEN' + CardCode, SUM(PayAmount) 
FROM BENSALEM.dbo.PWZ3
INNER JOIN BENSALEM.dbo.OPWZ T5 ON T5.IdNumber = IdEntry
WHERE T5.PmntDate = '4/1/2011' 
AND T5.Canceled = 'N' 
AND Checked = 'Y'
GROUP BY CardCode

UNION ALL  -- combine the two
SELECT 'BEN' + CardCode, PayAmount  -- not aggregating here, this will return all rows
FROM BENSALEM.dbo.PWZ3
INNER JOIN BENSALEM.dbo.OPWZ T5 ON T5.IdNumber = IdEntry
WHERE T5.PmntDate = '4/1/2011' 
AND T5.Canceled = 'N' 
AND Checked = 'Y'

编辑:由于您在评论中指定了MS SQL Server,因此Martin指出您可以使用ROLLUP在一个查询中执行此操作。 Read the MSDN doc on ROLLUP here

答案 2 :(得分:1)

SELECT 'BEN' + CardCode, BENSALEM.dbo.PWZ3.*,
       SUM(PayAmount) OVER (PARTITION BY CardCode) sum_PayAmount
  FROM BENSALEM.dbo.PWZ3
 INNER JOIN BENSALEM.dbo.OPWZ T5 ON T5.IdNumber = IdEntry
 WHERE T5.PmntDate = '4/1/2011' 
   AND T5.Canceled = 'N' 
   AND Checked = 'Y'

答案 3 :(得分:0)

您必须使用第二个查询来检索所需的数据。使用GROUP BY时,您只能按列分组为每个唯一值检索一行。通常,您添加到选择列表的任何字段都将返回组中第一行的值。

显然,像SUM这样的聚合函数会返回组中所有值的函数结果。