2010-12-11 97 views
4

列的變化查詢,我有表,其中包括我的產品表的日誌這樣的:這說明從表

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 

如何編寫此查詢?

回答

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. 
+0

非常感謝朋友。 – mavera 2010-12-12 14:05:26

+0

這可能救了我幾個小時的工作:) – chris 2011-08-19 18:52:50

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) 
+0

感謝您的回覆。你和Jurgen的解決方案幫助了我。 – mavera 2010-12-12 14:06:07