匹配之前和当前的记录,有和没有滞后和铅

时间:2019-04-15 10:24:48

标签: sql sql-server

我有如下表格。记录没有任何主键,我想同时使用WITH和WITHOUT LAG和LEAD功能。

ID      ENTID     INOUTDATE             YEAR    MONTH   STATUS
1923    1923    [NULL]                  2099     12      Out
1923    10690   [NULL]                  2099     12      Out
1923    9670    2012-08-24 00:00:00     2012     8       In
1923    1923    2013-06-01 00:00:00     2013     6       In
1923    9670    2018-04-19 00:00:00     2018     4       Out
1923    10690   2019-02-01 00:00:00     2019     2       In

我想获得以下记录。

ID      ENTID     INOUTDATE             YEAR    MONTH   STATUS
1923    10690   [NULL]                  2099    12      Out
1923    9670    2012-08-24 00:00:00     2012    8       In
1923    9670    2018-04-19 00:00:00     2018    4       Out
1923    10690   2019-02-01 00:00:00     2019    2       In

1 个答案:

答案 0 :(得分:1)

lag()是最简单的方法:

select t.*
from (select t.*, 
             lag(status) over (partition by id, (case when inoutdate is null then 1 else 2 end)
                               order by inoutdate
                              ) as prev_status
      from t
     ) t
where prev_status is null or prev_status <> status;

您可以将其视为“群岛问题”,使用row_number()识别岛屿。逻辑更复杂:

select t.*
from (select t.*, 
             row_number() over (partition by id, (case when inoutdate is null then 1 else 2 end), status, (seqnum - seqnum_s)
                                order by inoutdate
                               ) as seqnum_g
      from (select t.*,
                   row_number() over (partition by id, (case when inoutdate is null then 1 else 2 end) order by inoutdate) as seqnum,
                   row_number() over (partition by id, (case when inoutdate is null then 1 else 2 end), status order by inoutdate) as seqnum_s
            from t
           ) t
     ) t
where seqnum_g = 1;