如何使用 Lead() 和 Lag() 获取第一个非空值

Posted

技术标签:

【中文标题】如何使用 Lead() 和 Lag() 获取第一个非空值【英文标题】:How to use Lead() and Lag() to get the first non null value 【发布时间】:2020-03-22 13:51:44 【问题描述】:

我有以下问题

SELECT tb2.event_id, 
       tb2.MENU_HINT, 
       tb2.EVENT_NAME, 
       tb2.Expr1003, 
       tb2.CountWinnerNotPrice55to89Runners0to1 AS columnCount, 
       tb2.SumWinnerNotPrice55to89Runners0to1 AS columSum, 
       lead(tb2.SumWinnerNotPrice55to89Runners0to1,1)  OVER(   order by tb2.expr1003) as lead1
FROM [dbo].[tblData2] tb2
WHERE tb2.Expr1003 = '01/01/2018 ';

并返回此表:

╔═══════════╦══════════════════════════╦═════════════════╦════════════╦═════════════╦══════════╦═══════╗
║ event_id  ║ MENU_HINT                ║ EVENT_NAME      ║ Expr1003   ║ columnCount ║ columSum ║ lead1 ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466815 ║ AUS / Long (AUS) 1st Jan ║ R4 1400m Hcap   ║ 01/01/2018 ║ 1           ║ 85.00    ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466809 ║ AUS / Long (AUS) 1st Jan ║ R1 1400m Mdn    ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466868 ║ AUS / MBdg (AUS) 1st Jan ║ R7 1206m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466189 ║ AUS / Inve (AUS) 1st Jan ║ R7 1400m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466864 ║ AUS / MBdg (AUS) 1st Jan ║ R5 1406m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138386493 ║ AUS / Rand (AUS) 1st Jan ║ R2 1600m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466862 ║ AUS / MBdg (AUS) 1st Jan ║ R4 904m Hcap    ║ 01/01/2018 ║ 0           ║ NULL     ║ 82.53 ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138386464 ║ AUS / Flem (AUS) 1st Jan ║ R5 1700m Hcap   ║ 01/01/2018 ║ 1           ║ 82.53    ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466813 ║ AUS / Long (AUS) 1st Jan ║ R3 1400m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138386488 ║ AUS / Asct (AUS) 1st Jan ║ R9 1200m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ 57.45 ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466522 ║ AUS / Morn (AUS) 1st Jan ║ R4 1200m Hcap   ║ 01/01/2018 ║ 1           ║ 57.45    ║ 65.00 ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138386468 ║ AUS / Flem (AUS) 1st Jan ║ R7 2800m Listed ║ 01/01/2018 ║ 1           ║ 65.00    ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466181 ║ AUS / Inve (AUS) 1st Jan ║ R3 1010m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466187 ║ AUS / Inve (AUS) 1st Jan ║ R6 1600m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138386486 ║ AUS / Asct (AUS) 1st Jan ║ R8 2400m Grp2   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138386480 ║ AUS / Asct (AUS) 1st Jan ║ R5 1600m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ 65.00 ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138386478 ║ AUS / Asct (AUS) 1st Jan ║ R4 1800m Grp3   ║ 01/01/2018 ║ 1           ║ 65.00    ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138386497 ║ AUS / Rand (AUS) 1st Jan ║ R4 1200m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138386476 ║ AUS / Asct (AUS) 1st Jan ║ R3 2200m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466177 ║ AUS / Inve (AUS) 1st Jan ║ R1 1010m Mdn    ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466856 ║ AUS / MBdg (AUS) 1st Jan ║ R1 904m Mdn     ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466518 ║ AUS / Morn (AUS) 1st Jan ║ R2 1200m 3yo    ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138386470 ║ AUS / Flem (AUS) 1st Jan ║ R8 1400m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138386466 ║ AUS / Flem (AUS) 1st Jan ║ R6 1200m Grp3   ║ 01/01/2018 ║ 0           ║ NULL     ║ 66.51 ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466191 ║ AUS / Inve (AUS) 1st Jan ║ R8 1400m Cup    ║ 01/01/2018 ║ 1           ║ 66.51    ║ NULL  ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466798 ║ AUS / Tera (AUS) 1st Jan ║ R5 1125m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ 70.00 ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138466821 ║ AUS / Long (AUS) 1st Jan ║ R7 1800m Hcap   ║ 01/01/2018 ║ 1           ║ 70.00    ║ 72.44 ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════╣
║ 138386462 ║ AUS / Flem (AUS) 1st Jan ║ R4 2000m Hcap   ║ 01/01/2018 ║ 1           ║ 72.44    ║ 72.42 ║
╚═══════════╩══════════════════════════╩═════════════════╩════════════╩═════════════╩══════════╩═══════╝

现在,我要做的是计算字段上第一个非空值的前导。例如,对于 event_id = 138466815,columnCount 为 85。 我希望“lead1”字段显示 82.53,这是下面的下一个非空值。然后稍后,对于 event_id = **138386464 ** "导致 1 显示 57.45(下面的下一个非空值)。

我不确定是否应该将参数传递给前导函数的偏移参数,但我不知道应该是哪个,也许是 Coalesce 的东西?我做不到。

只是说得更清楚一点,这就是我希望lead1 列显示的内容:

╔═══════════╦══════════════════════════╦═════════════════╦════════════╦═════════════╦══════════╦═══════════════╗
║ event_id  ║ MENU_HINT                ║ EVENT_NAME      ║ Expr1003   ║ columnCount ║ columSum ║ lead1         ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466815 ║ AUS / Long (AUS) 1st Jan ║ R4 1400m Hcap   ║ 01/01/2018 ║ 1           ║ 85.00    ║ 82.53         ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466809 ║ AUS / Long (AUS) 1st Jan ║ R1 1400m Mdn    ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466868 ║ AUS / MBdg (AUS) 1st Jan ║ R7 1206m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466189 ║ AUS / Inve (AUS) 1st Jan ║ R7 1400m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466864 ║ AUS / MBdg (AUS) 1st Jan ║ R5 1406m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138386493 ║ AUS / Rand (AUS) 1st Jan ║ R2 1600m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466862 ║ AUS / MBdg (AUS) 1st Jan ║ R4 904m Hcap    ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138386464 ║ AUS / Flem (AUS) 1st Jan ║ R5 1700m Hcap   ║ 01/01/2018 ║ 1           ║ 82.53    ║ 57.45         ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466813 ║ AUS / Long (AUS) 1st Jan ║ R3 1400m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138386488 ║ AUS / Asct (AUS) 1st Jan ║ R9 1200m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466522 ║ AUS / Morn (AUS) 1st Jan ║ R4 1200m Hcap   ║ 01/01/2018 ║ 1           ║ 57.45    ║ 65.00         ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138386468 ║ AUS / Flem (AUS) 1st Jan ║ R7 2800m Listed ║ 01/01/2018 ║ 1           ║ 65.00    ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466181 ║ AUS / Inve (AUS) 1st Jan ║ R3 1010m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466187 ║ AUS / Inve (AUS) 1st Jan ║ R6 1600m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138386486 ║ AUS / Asct (AUS) 1st Jan ║ R8 2400m Grp2   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138386480 ║ AUS / Asct (AUS) 1st Jan ║ R5 1600m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138386478 ║ AUS / Asct (AUS) 1st Jan ║ R4 1800m Grp3   ║ 01/01/2018 ║ 1           ║ 65.00    ║ 66.51         ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138386497 ║ AUS / Rand (AUS) 1st Jan ║ R4 1200m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138386476 ║ AUS / Asct (AUS) 1st Jan ║ R3 2200m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466177 ║ AUS / Inve (AUS) 1st Jan ║ R1 1010m Mdn    ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466856 ║ AUS / MBdg (AUS) 1st Jan ║ R1 904m Mdn     ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466518 ║ AUS / Morn (AUS) 1st Jan ║ R2 1200m 3yo    ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138386470 ║ AUS / Flem (AUS) 1st Jan ║ R8 1400m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138386466 ║ AUS / Flem (AUS) 1st Jan ║ R6 1200m Grp3   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466191 ║ AUS / Inve (AUS) 1st Jan ║ R8 1400m Cup    ║ 01/01/2018 ║ 1           ║ 66.51    ║ 70.00         ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466798 ║ AUS / Tera (AUS) 1st Jan ║ R5 1125m Hcap   ║ 01/01/2018 ║ 0           ║ NULL     ║ NULL          ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138466821 ║ AUS / Long (AUS) 1st Jan ║ R7 1800m Hcap   ║ 01/01/2018 ║ 1           ║ 70.00    ║ 72.44         ║
╠═══════════╬══════════════════════════╬═════════════════╬════════════╬═════════════╬══════════╬═══════════════╣
║ 138386462 ║ AUS / Flem (AUS) 1st Jan ║ R4 2000m Hcap   ║ 01/01/2018 ║ 1           ║ 72.44    ║ next not null ║
╚═══════════╩══════════════════════════╩═════════════════╩════════════╩═════════════╩══════════╩═══════════════╝

另外,我不确定是否有办法计算“columnCount”中第一个非空值和第二个非空值之间的行数。例如将 7 作为第一个计数,将 3 作为第二个计数,将 1 作为第三个计数。

【问题讨论】:

【参考方案1】:

您似乎想要columnCount = 1 的下一个值,因此按该列分区:

   lead(tb2.SumWinnerNotPrice55to89Runners0to1, 1) over
       (partition by columnCount
        order by tb2.expr1003
       ) as lead1

【讨论】:

这有点解决了,但有没有办法做到并保持秩序?此方法确实以正确的方式对其进行分组,但顺序混乱,我需要像现在一样拥有它,原始表按 Expr1003 desc,raceno desc 排序。我已将此添加到lead(),但它似乎不起作用 @Baldie47 。 . .表没有排序。如果您希望结果按特定顺序排列,则需要在查询中添加order by 子句;在你的情况下,order by exp_1003, raceno desc. 这最终运行良好,由于 exp_1003 和 raceno 组合不是唯一的,所以我错过了三分之一字段 (event_id) 的排序,因此它是混合结果排序

以上是关于如何使用 Lead() 和 Lag() 获取第一个非空值的主要内容,如果未能解决你的问题,请参考以下文章

SQL SERVER LEAD和LAG使用

MYSQL lag() 和lead()函数使用介绍

如何为不同的观察组使用 LAG 和 LEAD 窗口函数

通过 LEAD/LAG 或递归 CTE 更新?

面试题: LEAD 和 LAG 求每个用户的页面停留时长

面试题: LEAD 和 LAG 求每个用户的页面停留时长