[英]SQL Server - SUM Preceding Rows With Condition Linked to Original Row
对于以下示例数据集中的每一行,当满足某个条件时,代码会对前 5 行进行求和。
我遇到的问题是条件需要引用原始行评级,例如,只有当评级在当前行的 1 以内时,我才需要对前面的行求和。
示例数据:
DECLARE @tbl TABLE
(
Team varchar(1),
date date,
Rating int,
Score int
);
INSERT INTO @tbl (Team, Date, Rating, Score)
VALUES
('a', '2020/12/05', '20', '1'),
('a', '2020/12/04', '18', '8'),
('a', '2020/12/03', '21', '3'),
('a', '2020/12/02', '19', '4'),
('a', '2020/12/01', '19', '3');
当前代码:
SELECT
Rating,
SUM(CASE WHEN Rating >= (Rating-1) AND Rating <= (Rating+1) THEN SCORE END)
OVER (partition by Team ORDER BY Date ASC ROWS BETWEEN 5 PRECEDING AND 1 PRECEDING) AS SUM
FROM
@tbl
ORDER BY
Date DESC
Output:
+------------------+------------+------------+
| Rating | Current | Required |
+------------------+------------+------------+
| 20 | 18 | 7 |
| 18 | 10 | 7 |
| 21 | 7 | NULL |
| 19 | 3 | 3 |
| 18 | NULL | NULL |
+------------------+------------+------------+
问题是代码的以下部分不起作用,因为正在逐行评估评级。
CASE WHEN Rating >= (Rating-1) AND Rating <= (Rating+1)
我需要它来评估原始行的评级(我已经查看了Top
但这不起作用):
CASE WHEN Rating >= ((SELECT TOP 1 Rating) - 1) AND Rating <= ((SELECT TOP 1 Rating) + 1)
一如既往地感谢任何帮助。
您所描述的听起来像是横向连接:
SELECT t.*, t2.*
FROM @tbl t OUTER APPLY
(SELECT SUM(t2.score) as score_5
FROM (SELECT TOP (5) t2.*
FROM @tbl t2
WHERE t2.date < t.date
ORDER BY t2.date DESC
) t2
WHERE t2.rating BETWEEN t.rating - 1 AND t.rating + 1
) t2
ORDER BY Date DESC
我不熟悉 sql 服务器语法,但这里是使用 Spark SQL 的方法。 本质上,这个想法是为每对彼此相距 5 行以内的行创建一行,然后sum if
。
select
Team, date, Rating,
sum(case when old_score[0] between rating-1 and rating+1 then old_score[1] end) as sum
from (
select
*,
explode_outer(scores) as old_score
from (
select
*,
collect_list(array(rating, score))
over (partition by Team order by date rows between 5 preceding and 1 preceding) scores
from tbl
)
)
group by Team, date, Rating
order by Team, date, Rating;
这使
a 2020-12-01 19 NULL
a 2020-12-02 19 3
a 2020-12-03 21 NULL
a 2020-12-04 18 7
a 2020-12-05 20 10
并表明您可能在预期的 output 中犯了错误;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.