滞后函数跳过前一个记录为空的记录

时间:2019-06-10 15:59:53

标签: sql sql-server

我正在尝试使用lag函数获取先前的值,但是它仅适用于填充在先前记录中的数据。我想做的是仅在存在空值时才跳过上一条记录,然后在不为空值的记录之前查看上一条记录

Select LAG(previous_reference_no)OVER(ORDER BY createdon) FROM TableA

所以说如果我在记录5处,记录4为空,但是记录3不为空。所以从记录5开始,我想显示记录4的值。

希望这很有意义,请帮助/

2 个答案:

答案 0 :(得分:1)

添加PARTITION BY子句?

Select LAG(previous_reference_no) OVER (PARTITION BY CASE WHEN previous_reference_no IS NULL THEN 0 ELSE 1 END
                                        ORDER BY createdon)
FROM TableA

答案 1 :(得分:1)

标准SQL的语法如下:

SELECT LAG(previous_reference_no IGNORE NULLS) OVER (ORDER BY createdon)
FROM TableA

不幸的是,SQL Server不支持此功能。一种方法使用两个级别的窗口函数和一些逻辑:

SELECT (CASE WHEN previous_reference_no IS NULL
             THEN MAX(prev_reference_no) OVER (PARTITION BY grp)
             ELSE LAG(previous_reference_no) OVER (PARTITION BY (CASE WHEN previous_reference_no IS NOT NULL THEN 1 ELSE 0 END)
                                                   ORDER BY createdon)
        END)
FROM (SELECT a.*,
             COUNT(prev_reference_no) OVER (ORDER BY a.createdon) as grp
      FROM TableA a
     ) a;

逻辑是:

  • 创建一个分组,该分组具有给定的参考编号,并在一组中包含所有以下NULL个值。
  • 如果参考号为NULL,则获取组开头的第一个值。这将是先前的非NULL值。
  • 如果参考编号不是NULL,则使用partition by查看最后一个非NULL值。

另一种方法-可能会慢得多-使用APPLY

select a.*, aprev.prev_reference_no
from TableA a outer apply
     (select top (1) aprev.*
      from TableA aprev
      where aprev.createdon < a.createdon and
            aprev.prev_reference_no is not null
     ) aprev;

对于一张小桌子,性能降低可能值得用代码的简单性来实现。