一个查询,显示表中列的更改

时间:2010-12-11 13:13:04

标签: sql oracle

我有一张表,其中包含我的产品表的日志:

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 个答案:

答案 0 :(得分:4)

像这样:

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.

答案 1 :(得分:2)

使用LAG analytic function查找product_type_id列的先前值。如果当前值和先前值不同,则应该是您想要的行。对于第一行,LAG函数将返回null,因为没有前一行,因此您还需要测试它。

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)