首页 > 解决方案 > 设置一个行值以重复直到下一个实例

问题描述

我收到了一张包含各种屏幕及其部分和部分 ID 值以及排序顺序的表格。一种类型的部分是标题,每个屏幕可以有多个。我需要在表中添加一个作为关联标题的列,当找到下一个标题时它将重置。

我尝试过使用 Lag 和 Lead,但它只能向后或向前看一条记录,并且屏幕上的部分数量是可变的,并且总是大于 1。

SELECT SCREEN, ID, TYPE, SORT
    , LAG(ID) OVER (ORDER BY SORT) PREVIOUS_TYPE
    , LEAD(ID) OVER (ORDER BY SORT) NEXT_TYPE
   , CASE WHEN ID LIKE 'X%' THEN ID
        ELSE LAG(ID) OVER (ORDER BY SORT) END HEADING
FROM T_1
ORDER BY SORT;

源数据:

屏幕 ID 类型排序
输入 X1 标题 1
输入 C123 发现 2
输入 D937 文本 3
输入 X2 标题 4
输入 C31 搜索 5
输入 G876 负 6
输入 M3838 风险 7
输出 X3 标题 8
输出 G72 图 9

预期输出:

屏幕标题 ID 类型排序
输入 X1 X1 标题 1
输入 X1 C123 发现 2
输入 X1 D937 文本 3
输入 X2 X2 标题 4
输入 X2 C31 搜索 5
输入 X2 G876 负 6
输入 X2 M3838 风险 7
输出 X3 X3 标题 8
输出 X3 G72 图 9

标签: sqlsql-servertsql

解决方案


您可以使用窗口函数。. . 两个层次。第一个根据标题的累积计数分配组。第二个分配值:

select t.*,
       max(case when type = 'Heading' then id end) over (partition by grp) as heading_id
from (select t.*,
             sum(case when type = 'Heading' then 1 else 0 end) over (order by sort) as grp
      from t
     ) t;

如果您碰巧知道标题 id 正在增加(如您问题中的数据所示),您可以使用累积max()

select t.*
       max(case when type = 'Heading' then id end) over (order by sort) as heading_id
from t;

推荐阅读