sql - 每 N 选择行并进行 SUM

标签 sql sql-server tsql

我的 SQL Server 数据库中有一个表,其中包含以下内容:

Date        | Amount
------------|----------
2012-12-17  | 9.00
2012-12-18  | 8.00
2012-12-19  | 0.00
2012-12-20  | 1.50
2012-12-21  | 2.50
2012-12-22  | 0.00
2012-12-23  | 0.00
2012-12-24  | 0.00
2012-12-25  | 0.00
2012-12-26  | 4.00
2012-12-27  | 2.00
2012-12-28  | 7.00

我想要做的是每次选择取 3 行,并对 Amount 进行SUM。如果SUM的总和是0,那么它应该删除这3条记录。否则,它应该不理会它们并获取接下来的 3 条记录并执行相同的检查。

因此,在这种情况下,只应从表中删除以下三个记录,因为它们是唯一 SUM 结果为 0 的记录。

2012-12-23  | 0.00
2012-12-24  | 0.00
2012-12-25  | 0.00

我怎样才能在 SQL Server 中完成他的任务?

最佳答案

您可以使用ROW_NUMBER来创建3个元素组并计算总和。

WITH cte AS
(
  SELECT *, rn = (ROW_NUMBER() OVER(ORDER BY [Date]) - 1) / 3
  FROM #tab
), cte2 AS
(
  SELECT *, [sum] = SUM(Amount) OVER (PARTITION BY rn ORDER BY [Date])
  FROM cte
)
SELECT *
FROM cte2
WHERE [sum] = 0;

LiveDemo

并使用删除:

WITH cte AS
(
   SELECT *, rn = (ROW_NUMBER() OVER(ORDER BY [Date]) - 1) / 3
   FROM #tab
), cte2 AS
(
   SELECT *, [sum] = SUM(Amount) OVER (PARTITION BY rn ORDER BY [Date])
   FROM cte
)
DELETE t
FROM #tab t
JOIN cte2 c
  ON t.[Date] = c.[Date]
WHERE [sum] = 0;

SELECT *
FROM #tab;

LiveDemo2

编辑:

如果您的数据可以包含负值,您可以使用:

WITH cte AS
(
  SELECT *, rn = (ROW_NUMBER() OVER(ORDER BY [Date]) - 1) / 3
  FROM #tab
), cte2 AS
(
  SELECT rn, [sum] = SUM(Amount)
  FROM cte
  GROUP BY rn
)
SELECT c.*
FROM cte c
JOIN cte2 c2
  ON c.rn = c2.rn
WHERE [sum] = 0;

LiveDemo3

关于sql - 每 N 选择行并进行 SUM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33542316/

相关文章:

sql - 在 MySQL 中对数据库表进行分区

sql-server - 如何在没有数据的情况下进行sql数据库备份

sql-server - 表值函数刷新

ruby-on-rails - rails 4 activerecord TypeError nil 不是一个符号

sql-server - TSQL、CASE 中的 SELECT 语句在 COUNT

sql - 向另一个数据库的用户/角色授予对一个数据库的访问权限

SQL Server -XML 节点不返回多条记录

mysql - SQL Server 管理工作室审查脚本,如 MySQL Workbench

sql - 这条SQL语句是什么意思?

mySQL 查询 - #1054 - 未知列 3