选择每N行,并执行SUM

Viv*_*ndi 5 sql t-sql sql-server

我的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
Run Code Online (Sandbox Code Playgroud)

我想要做的就是采取每选择3行SUMAmount.如果总数SUM0,则应删除这3条记录.否则它应该只留下它们并采取接下来的3条记录并进行相同的检查.

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

2012-12-23  | 0.00
2012-12-24  | 0.00
2012-12-25  | 0.00
Run Code Online (Sandbox Code Playgroud)

我怎样才能在SQL Server中完成他的工作?

Luk*_*zda 6

您可以使用ROW_NUMBER3个元素组和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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

LiveDemo3