SQL Server - 前非空行的平均值

问题描述

我正在尝试对前两行做一个简单的平均。复杂的部分是如果分数列中的一行包含 NULL,我想计算最后 2 个非 NULL 行的平均值。

按非空排序不起作用,因为它将当前行与其他非空行放在一起。类似地,创建一个单独的非空行号会产生同样的问题。我假设我必须通过外连接解决,但只是检查是否有人知道对以下代码进行更简单的调整)。

示例数据:

DECLARE @tbl TABLE 
             (
                 Team varchar(1),date date,score int
             );

    INSERT INTO @tbl (Team,Date,score)
    VALUES
    ('a','2020/12/05',null),('a','2020/12/04','2020/12/03','2020/12/02','2020/11/04','2'),'2020/10/03','4'),'2020/08/02','6'),'2020/06/01','8');

SELECT
    date,avg(score+0.0) OVER (partition by Team ORDER BY Date ASC ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS Average
FROM
    @tbl
ORDER BY 
    Date DESC

输出

    +--------+------------+------------+
    |  Row   | Current    | required   | 
    +--------+------------+------------+
    | 1      | NULL       |     3      |
    | 2      | NULL       |     3      |
    | 3      | 2          |     3      |
    | 4      | 3          |     3      |
    | 5      | 5          |     5      |
    | 6      | 7          |     7      |
    | 7      | 8          |     8      |
    | 8      | NULL       |     NULL   |
    +--------+------------+------------+

解决方法

您可以使用带有 top 子句的子查询:

<custom>

演示:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=5ad91643b0fa21fe8a78b78ded1ce498

,

我不熟悉 MSSQL,但这可能有效。

在使用窗口函数之前,您可以尝试将表格包装在 CTE 中,例如

WITH tbl_CTE (Team,Date,Score)  
AS  
(  
    SELECT *
    FROM @tbl
    WHERE Score IS NOT NULL  
)  
SELECT
    date,avg(SCORE+0.0) OVER (partition by Team ORDER BY Date ASC ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS Average
FROM
    tbl_CTE
ORDER BY 
    Date DESC
;