0
   Date           ID       X or Y 
-------------------------------
01.01.2016       1234        Y
01.01.2017       1234        X
01.01.2018       1234        Y
01.01.2019       1234        Y
01.01.2020       1234        Y
01.01.2021       1234        X
01.01.2016       4321        X
01.01.2017       4321        X
01.01.2018       4321        X
01.01.2019       4321        Y
01.01.2020       4321        Y

上表显示了我正在使用的数据的结构。我想要做的是将它减少到另一个表,其中我只有与 X/Y 状态变化相关的行;但是,我不仅需要 X 变为 Y 之后的第一次观察(反之亦然),还需要 change 之前的最后一次观察。在 Oracle 数据库上运行 SQL 时,如何实现与下表完全相同的输出?

   Date           ID       X or Y 
-------------------------------
01.01.2016       1234        Y
01.01.2017       1234        X
01.01.2018       1234        Y
01.01.2020       1234        Y
01.01.2021       1234        X
01.01.2018       4321        X
01.01.2019       4321        Y
4

2 回答 2

3

这是一个选项:

  • 第 1 - 14 行的样本数据
  • TEMPCTE:上一个 ( LAG) 和下一个 ( LEAD) x/y 值 per ID,按日期值排序
  • finalselect检索结果

SQL> with test (datum, id, xy) as
  2    (select date '2016-01-01', 1234, 'y' from dual union all
  3     select date '2017-01-01', 1234, 'x' from dual union all
  4     select date '2018-01-01', 1234, 'y' from dual union all
  5     select date '2019-01-01', 1234, 'y' from dual union all
  6     select date '2020-01-01', 1234, 'y' from dual union all
  7     select date '2021-01-01', 1234, 'x' from dual union all
  8     --
  9     select date '2016-01-01', 4321, 'x' from dual union all
 10     select date '2017-01-01', 4321, 'x' from dual union all
 11     select date '2018-01-01', 4321, 'x' from dual union all
 12     select date '2019-01-01', 4321, 'y' from dual union all
 13     select date '2020-01-01', 4321, 'y' from dual
 14    ),
 15  temp as
 16    (select datum, id, xy,
 17       lag(xy)  over (partition by id order by datum) laxy,
 18       lead(xy) over (partition by id order by datum) lexy
 19     from test
 20    )
 21  --
 22  select datum, id, xy
 23  from temp
 24  where xy <> laxy or xy <> lexy
 25  order by id, datum;

DATUM              ID X
---------- ---------- -
01.01.2016       1234 y
01.01.2017       1234 x
01.01.2018       1234 y
01.01.2020       1234 y
01.01.2021       1234 x
01.01.2018       4321 x
01.01.2019       4321 y

7 rows selected.

SQL>
于 2020-08-26T07:35:03.120 回答
2

似乎您需要一起使用LEAD()LAG()功能来过滤它们:

WITH t2 AS
(
SELECT t.*,
       LAG(x_y,1,x_y) OVER (PARTITION BY id ORDER BY id, dt) AS lg_xy,
       LEAD(x_y,1,x_y) OVER (PARTITION BY id ORDER BY id, dt) AS ld_xy
  FROM t
 ORDER BY id, dt 
) 
SELECT dt, id, x_y
  FROM t2
 WHERE NOT ( x_y = lg_xy AND x_y = ld_xy )

Demo

于 2020-08-26T07:37:01.723 回答