选择每N行,并执行SUM

时间:2015-11-05 10:34:08

标签: 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行,SUM Amount。如果SUM的总和为0,则应删除这3条记录。否则它应该只留下它们并接下来的3条记录并进行相同的检查。

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

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

如何在SQL Server中执行此操作?

1 个答案:

答案 0 :(得分:6)

您可以使用ROW_NUMBER制作3个元素组和calucalte sum。

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

使用DELETE

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