【问题标题】:Is it possible to ignore NULL values when using LAG() and LEAD() functions in SQL Server?在 SQL Server 中使用 LAG() 和 LEAD() 函数时是否可以忽略 NULL 值?
【发布时间】:2014-06-21 03:56:05
【问题描述】:

如您所知,LAG() 和 LEAD() 分析函数可以访问同一结果集中的前一行和下一行的数据,而无需使用自联接。但是在访问 NOT NULL 值之前是否可以忽略 NULL 值?

【问题讨论】:

    标签: sql sql-server-2012


    【解决方案1】:

    可以使用窗口函数。 阅读 Itzik Ben-Gan 的 article 了解更多详情。

    在下面的代码中,cte 获取最新的 NOT NULL id 值,然后下一个选择获取实际列值。此示例使用 LAG。 例如。

    -- DDL for T1
    SET NOCOUNT ON;
    USE tempdb;
    IF OBJECT_ID(N'dbo.T1', N'U') IS NOT NULL DROP TABLE dbo.T1;
    GO
    CREATE TABLE dbo.T1
    (
    id INT NOT NULL CONSTRAINT PK_T1 PRIMARY KEY,
    col1 INT NULL
    );
    
    -- Small set of sample data
    TRUNCATE TABLE dbo.T1;
    
    INSERT INTO dbo.T1(id, col1) VALUES
    ( 2, NULL),
    ( 3,   10),
    ( 5,   -1),
    ( 7, NULL),
    (11, NULL),
    (13,  -12),
    (17, NULL),
    (19, NULL),
    (23, 1759);
    
    ;WITH C AS
    (
    SELECT
        id, 
        col1, 
        MAX(CASE WHEN col1 IS NOT NULL THEN id END) OVER(ORDER BY id ROWS UNBOUNDED PRECEDING) AS grp
    FROM dbo.T1
    )
    SELECT
        id, 
        col1, 
        (SELECT col1 FROM dbo.T1 WHERE id = grp) lastval    
    FROM C;
    

    【讨论】:

    【解决方案2】:

    Oracle 11 支持选项ignore nulls,这正是您想要的。当然,您的问题是关于 SQL Server 的,但有时知道该功能确实存在于某处令人振奋。

    可以模拟此功能。这个想法是根据前面的值将空值分配给一个组。本质上,这是在计算它之前的非空值的数量。您可以使用相关子查询来执行此操作。或者,更有趣的是,两个行号的差异。然后在组内,你可以使用max()

    我认为以下内容可以满足您的要求。假设col 包含NULL 值并且ordering 具有行的顺序:

    select t.*,
           max(col) over (partition by grp) as LagOnNull
    from (select t.*,
                 (row_number() over (order by ordering) - 
                  row_number() over (partition by col order by ordering)
                 ) as grp
          from table t
         ) t;
    

    lead() 类似,但顺序相反。而且,这将与其他分区键一起使用,但您需要将它们添加到所有窗口表达式中。

    【讨论】:

    • 感谢您的回答戈登。但我不明白这个示例中的“col2”是什么?
    • col2 应该是 collag()/lead() 的参数。
    • 创意解决方案戈登。但不幸的是对我不起作用:(
    • @Mostapha777 。 . .这确实可以忽略NULLs 的lag() 1(我应该在答案中提到)。如果它对您不起作用,您应该使用您尝试过的查询来编辑您的问题。您必须在各种分析函数上正确使用分区子句。
    【解决方案3】:
    LEAD(IIF(col1 IS NULL,NULL, col1),1) OVER PARTITION BY (ISNULL(col1))
    

    【讨论】:

      猜你喜欢
      • 2018-12-12
      • 1970-01-01
      • 2022-11-23
      • 2016-09-19
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多