SQL Server - 将条件链接到原始行的 SUM 前面的行

Posted

技术标签:

【中文标题】SQL Server - 将条件链接到原始行的 SUM 前面的行【英文标题】:SQL Server - SUM Preceding Rows With Condition Linked to Original Row 【发布时间】:2020-12-05 17:10:43 【问题描述】:

对于下面示例数据集中的每一行,代码在满足特定条件时对前 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

输出:

    +------------------+------------+------------+
    |  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)

一如既往地感谢任何帮助。

【问题讨论】:

您对使用ratingRating 有何期望? 抱歉。应该都是评分。我会编辑帖子。 顺便说明一下:SQL Server 2008 和 2008 R2 目前完全不受支持(甚至超出了扩展支持) - red-gate.com/simple-talk/sql/database-administration/… - 是时候升级了!跨度> 发布了不正确的版本。将帖子更新到 2017 年。感谢您的指出。 【参考方案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

【讨论】:

谢谢分享。我用示例数据尝试了代码,但出现错误。我将尝试横向连接的想法。 通过小改动让它工作(等待更改获得批准,我会接受)。感谢您的帮助。【参考方案2】:

我不熟悉 sql server 语法,但这里是使用 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

并表明您可能在预期输出中犯了错误;)

【讨论】:

感谢您的分享和想法。我会四处玩耍并尝试重新创建。

以上是关于SQL Server - 将条件链接到原始行的 SUM 前面的行的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Server 触发器中复制插入、更新、删除的行

将数据从 Power BI 导出到 SQL Server 突破了 150k 行的限制

SQL Server Reporting Services 2005 超链接值?

根据条件将单个数据行拆分为多个数据行的 SQL 脚本

SQL Server:从链接到另一个表的 ID 列动态创建列

sql server链接查询