设置一个行值重复直到下一个实例

时间:2019-07-25 13:41:06

标签: sql sql-server tsql

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

我尝试使用滞后和提前,但是它只向后或向前浏览一条记录,并且屏幕上的部分数是可变的,并且总是大于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;

源数据:

SCREEN   ID     TYPE      SORT
INPUT    X1     Heading    1
INPUT    C123   Finding    2
INPUT    D937   Text       3
INPUT    X2     Heading    4
INPUT    C31    Search     5
INPUT    G876   Negative   6
INPUT    M3838  Risk       7
OUTPUT   X3     Heading    8
OUTPUT   G72    Map        9

预期输出:

SCREEN  HEADING ID     TYPE       SORT
INPUT     X1    X1     Heading     1
INPUT     X1    C123   Finding     2
INPUT     X1    D937   Text        3
INPUT     X2    X2     Heading     4
INPUT     X2    C31    Search      5
INPUT     X2    G876   Negative    6
INPUT     X2    M3838  Risk        7
OUTPUT    X3    X3     Heading     8
OUTPUT    X3    G72    Map         9

3 个答案:

答案 0 :(得分:1)

您可以使用窗口功能。 。 。两个层次。首先根据标题的累计数量分配组。第二个分配值:

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;

答案 1 :(得分:0)

我会尝试将其分成几部分-首先获得唯一的标题,然后将它们加入其余数据。我想不出一种通过简单的连接使其工作的方法,所以我改用apply

with headings as (
  select SCREEN, [ID], [SORT]
  from T_1
  where [TYPE] = 'Heading'
)
select t_1.[SCREEN], h_1.HEADING, t_1.[ID], t_1.[TYPE], t_1.[SORT]         
from t_1
outer apply (
  select top 1 h.[ID] AS HEADING
  from headings h
  where h.[SCREEN] = t_1.[SCREEN]
    and h.[SORT] <= t_1.[SORT]
  order by h.[SORT] desc
) h_1

http://sqlfiddle.com/#!18/fbb75/5

答案 2 :(得分:0)

这应该起作用:

  SELECT t.SCREEN, t.ID, t.TYPE, t.SORT,
    (SELECT  TOP 1 h.ID  FROM T_1 h WHERE h.SCREEN=t.SCREEN AND h.SORT<=t.SORT AND h.TYPE='Heading' ORDER BY h.SORT DESC) AS HEADING
    FROM T_1 t