Запрос, который показывает изменения столбца из таблицы - PullRequest
4 голосов
/ 11 декабря 2010

у меня есть таблица, в которую входят журналы моей таблицы продуктов, например:

process_time             product_id  product_type_id
04.07.2009 14:08:43      5           4
05.07.2009 15:08:43      5           4
06.07.2009 16:08:43      5           6
07.07.2009 16:08:43      5           6
08.07.2009 17:08:43      5           4
08.07.2009 18:08:43      5           4

Я хочу написать запрос, который показывает изменения product_type_id.Для приведенного выше примера результат моего запроса должен быть таким:

process_time             product_id  product_type_id
04.07.2009 14:08:43      5           4
06.07.2009 16:08:43      5           6
08.07.2009 17:08:43      5           4

Как мне написать этот запрос?

Ответы [ 2 ]

4 голосов
/ 11 декабря 2010

Вот так:

select * from
(select process_time, product_id, product_type_id
,lag(product_type_id) over (partition by product_id order by process_time) as prevrow
,lead(product_type_id) over (partition by product_id order by process_time) as nextrow
from products )
where nextrow <> product_type_id or nextrow is null;

Для всех, кому нравится видеть, как это работает:

create table products (process_time  timestamp, product_id number, product_type_id number);

insert into products values (to_date('2009-07-04 14:08:43','YYYY-MM-DD hh24:mi:ss'),5,4);
insert into products values (to_date('2009-07-05 15:08:43','YYYY-MM-DD hh24:mi:ss'),5,4);
insert into products values (to_date('2009-07-06 16:08:43','YYYY-MM-DD hh24:mi:ss'),5,6);
insert into products values (to_date('2009-07-07 16:08:43','YYYY-MM-DD hh24:mi:ss'),5,6);
insert into products values (to_date('2009-07-08 17:08:43','YYYY-MM-DD hh24:mi:ss'),5,4);
insert into products values (to_date('2009-07-08 18:08:43','YYYY-MM-DD hh24:mi:ss'),5,4);

commit;

select process_time, product_id, product_type_id
,lag(product_type_id) over (partition by product_id order by process_time) as prevrow
,lead(product_type_id) over (partition by product_id order by process_time) as nextrow
from products 
order by process_time;

select * from
(select process_time, product_id, product_type_id
,lag(product_type_id) over (partition by product_id order by process_time) as prevrow
,lead(product_type_id) over (partition by product_id order by process_time) as nextrow
from products )
where nextrow <> product_type_id or nextrow is null;

commit;

drop table products;

Выполнено, мы получаем:

Table created.
1 row created.
1 row created.
1 row created.
1 row created.
1 row created.
1 row created.
Commit complete.

PROCESS_TIME                    PRODUCT_ID PRODUCT_TYPE_ID    PREVROW    NEXTROW
------------------------------- ---------- --------------- ---------- ----------
04-JUL-09 02.08.43.000000 PM             5               4                     4
05-JUL-09 03.08.43.000000 PM             5               4          4          6
06-JUL-09 04.08.43.000000 PM             5               6          4          6
07-JUL-09 04.08.43.000000 PM             5               6          6          4
08-JUL-09 05.08.43.000000 PM             5               4          6          4
08-JUL-09 06.08.43.000000 PM             5               4          4           


6 rows selected.

PROCESS_TIME                    PRODUCT_ID PRODUCT_TYPE_ID    PREVROW    NEXTROW
------------------------------- ---------- --------------- ---------- ----------
05-JUL-09 03.08.43.000000 PM             5               4          4          6
07-JUL-09 04.08.43.000000 PM             5               6          6          4
08-JUL-09 06.08.43.000000 PM             5               4          4           


3 rows selected.
Commit complete.
Table dropped.
2 голосов
/ 11 декабря 2010

Используйте аналитическую функцию LAG , чтобы найти предыдущее значение столбца product_type_id. Если текущие и предыдущие значения отличаются, то это должна быть строка, которую вы хотите. Для первой строки функция LAG вернет ноль, так как предыдущей строки нет, поэтому вам также необходимо проверить это.

select 
  process_time, 
  product_id, 
  product_type_id, 
from (
  select 
    process_time, 
    product_id, 
    product_type_id, 
    lag(product_type_id) over (order by process_time) as prior_product_type_id
  from the_table
)
where 
  (prior_product_type_id <> product_type_id or prior_product_type_id is null)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...