在另一列中查找第一个非 null 值,其顺序为 by 和 group by

Find the first non null value in another column with arbitrary order by and group by

提问人:zle_bi 提问时间:11/14/2023 最后编辑:Xednizle_bi 更新时间:11/15/2023 访问量:83

问:

给定以下示例数据...

drop table if exists #data
create table #data
(
    Id char(3),
    Date1 date,
    Date2 date
)
insert into #data (Id, Date1, Date2)
values
    ('100', '2017-02-24', null),
    ('100', '2017-03-06', null),
    ('100', '2017-03-21', '2017-04-04'),
    ('100', '2017-06-15', null),
    ('100', '2017-06-16', '2017-06-16'),
    ('100', '2017-11-17', null),
    ('100', '2018-02-02', null),
    ('200', '2017-06-06', '2017-06-11'),
    ('200', '2018-02-02', null),
    ('200', '2018-02-08', null),
    ('200', '2018-02-09', null),
    ('200', '2018-02-14', '2018-02-15'),
    ('200', '2018-03-03', '2018-03-07'),
    ('200', '2018-06-07', '2018-06-14')

我想从这两列创建一个新列,该列采用值:[new_date][DATE_1][DATE_2]

  • 如果以前的值为 NULL,则小于最小值。[DATE_1][DATE_2][DATE_2]

  • 大于 和 的 MIN,其 null 值为[DATE_1][DATE_2][DATE_2]

  • 否则,如果前一个和 之间没有 NULL 值,则它是前一个 和[DATE_1][DATE_2][DATE_2][Date_2][Date_2]

对于每个 ID,日期应按升序排序。

我想使用屏幕截图中共享的 SQL 查询获取结果

enter image description here

sql sql-server t-sql

评论

4赞 GuidoG 11/14/2023
如果您包含一些示例数据和预期结果,您将获得更多答案,但不要将它们添加到图像中,而是将它们添加为我们可以复制/粘贴的文本
0赞 Peter Smith 11/14/2023
MySQL 与 sql-server 不同
0赞 T N 11/15/2023
请将您的数据的文本表示剪切并粘贴到您的问题中。如果您不确定格式,请粘贴原始数据,有人可以帮助格式化。
0赞 Xedni 11/15/2023
是否需要分组结果集?或者,当不是您指示的值之一时,我们是否应该假设 中的任何值都是 null?NewDate
1赞 T N 11/15/2023
感谢@Xedni转录数据。

答:

1赞 T N 11/15/2023 #1

关键是首先将数据分区为行组,其中每个组以非 null 值结尾。这可以使用精心设计的窗口函数来完成。这可以封装在提供最终选择的公用表表达式 (CTE) 中。最终选择可以使用窗口函数有条件地选择每个组中的最小值。DATE_2COUNT() OVER()DATE_1MIN() OVER()

像这样:

;WITH CTE_Grouped AS (
    SELECT *,
        COUNT(DATE_2) OVER(
                PARTITION BY ID
                ORDER BY DATE_1
                ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
            ) AS GroupNum
    FROM Data D
)
SELECT
    G.ID, G.DATE_1, G.DATE_2, G.GroupNum,
    CASE WHEN G.DATE_2 IS NOT NULL
        THEN MIN(G.DATE_1) OVER(PARTITION BY G.ID, G.GroupNum)
        END AS new_date
FROM CTE_Grouped G
ORDER BY G.ID, G.DATE_1

结果:

编号 DATE_1 DATE_2 GroupNum (组编号) new_date
100 2017-02-24 0
100 2017-03-06 0
100 2017-03-21 2017-04-04 0 2017-02-24
100 2017-06-15 1
100 2017-06-16 2017-06-16 1 2017-06-15
100 2017-11-17 2
100 2018-02-02 2
200 2017-06-06 2017-06-11 0 2017-06-06
200 2018-02-02 1
200 2018-02-08 1
200 2018-02-09 1
200 2018-02-14 2018-02-15 1 2018-02-02
200 2018-03-03 2018-03-07 2 2018-03-03
200 2018-06-07 2018-06-14 3 2018-06-07

请参阅此 db<>fiddle