SQL 服务器 - 前面的非空行的平均值

SQL Server - Average preceding Not Null rows

我正在尝试对前两行进行简单平均。复杂的部分是如果一行在分数列中包含 NULL,我想对最后 2 个 NON 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', null),
    ('a', '2020/12/03', null),
    ('a', '2020/12/02', null),
    ('a', '2020/11/04', '2'),
    ('a', '2020/10/03', '4'),
    ('a', '2020/08/02', '6'),
    ('a', '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   |
    +--------+------------+------------+

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

您可以尝试在使用 Window 函数之前将 table 包装在 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
;

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

SELECT
  date,
  (
    SELECT AVG(score+0.0)
    FROM
    (
      SELECT TOP(2) score
      FROM @tbl t2
      WHERE t2.date < t1.date
      AND t2.score IS NOT NULL
      ORDER BY t2.date DESC
    ) two_previous
  ) as average
FROM @tbl t1
ORDER BY date DESC;

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