2010-12-11 8 views
4

i ont la table qui comprennent les journaux de ma table de produit comme ça:Une requête qui montre les changements d'une colonne d'une table

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 

Je veux écrire une requête qui montre les changements de product_type_id. Pour l'exemple ci-dessus, le résultat de ma requête doit être comme ceci:

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 

Comment puis-je écrire cette requête?

Répondre

4

Comme ceci:

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; 

Pour tous ceux qui aiment voir comment cela fonctionne:

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; 

Exécuté nous obtenons:

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

Merci beaucoup. – mavera

+0

Cela m'a probablement sauvé plusieurs heures de travail :) – chris

2

Utilisez le LAG analytic function pour trouver la valeur avant de la colonne product_type_id. Si les valeurs actuelles et antérieures sont différentes, cela devrait être la ligne que vous voulez. Pour la première ligne, la fonction LAG renverra null car il n'y a pas de ligne précédente, donc vous devrez également tester pour cela.

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

Merci pour votre réponse. Votre solution et celle de Jurgen m'ont aidé. – mavera

Questions connexes