2010-12-07 86 views
0

Étant donné l'ensemble d'enregistrements suivant, j'aimerais retourner la première occurrence de l'enregistrement 'modifié'.Requête Oracle renvoyant des enregistrements pour un changement de séquence d'une valeur de champ

Étant donné (domaines pertinents):


ID STATE REF  DATE 
1  state_1 x  2010-12-01 
2  state_1 x  2010-12-02 
3  state_2 x  2010-12-02 
4  state_2 x  2010-12-02 
5  state_1 Y  2010-12-03 
6  state_3 x  2010-12-03 
7  state_4 x  2010-12-03 
8  state_2 x  2010-12-03 
9  state_1 x  2010-12-03 
10 state_1 x  2010-12-04 
11 state_2 x  2010-12-04 
 

retour souhaité (pour réf objet X):


ID STATE REF  DATE 
1  state_1 x  2010-12-01 
3  state_2 x  2010-12-02 
6  state_3 x  2010-12-03 
7  state_4 x  2010-12-03 
8  state_2 x  2010-12-03 
9  state_1 x  2010-12-03 
11 state_2 x  2010-12-04 

Des explications complémentaires: Ceci est une table d'audit qui maintient l'état d'objets, et je voudrais suivre les dates qu'un changement est survenu à l'état d'un certain objet. Je joue avec des agrégats/analytiques, mais je commence à me demander s'ils pourraient m'amener n'importe où.

+0

La réponse de Rajesh est proche, sauf qu'elle inclut également l'ID 8. Mais il semble que l'ID 8 devrait être dans les résultats. –

+0

Vous avez raison - la réponse de Rajesh semble logique (et génial). ID 8 est une faute de frappe de ma part - des excuses - mais la requête de Rajesh devrait le capturer. Je l'ajoute à la liste des résultats souhaités. Je vais tester la réponse bientôt. – tamersalama

+0

J'ai modifié le post pour inclure les résultats et les scripts. –

Répondre

2

Essayez la requête suivante. Fondamentalement, vous devez obtenir la valeur suivante de STATE Colum et afficher la ligne courante si l'état précédent est différent de l'état actuel.

create table state_data(
    id number, 
    state varchar2(20), 
    ref varchar2(1), 
    date1 date); 


insert into state_data values (1  ,'state_1','x',to_date('2010-12-01','YYYY-MM-DD')); 
insert into state_data values (2  ,'state_1','x',to_date('2010-12-02','YYYY-MM-DD')); 
insert into state_data values (3  ,'state_2','x',to_date('2010-12-02','YYYY-MM-DD')); 
insert into state_data values (4  ,'state_2','x',to_date('2010-12-02','YYYY-MM-DD')); 
insert into state_data values (5  ,'state_1','Y',to_date('2010-12-03','YYYY-MM-DD')); 
insert into state_data values (6  ,'state_3','x',to_date('2010-12-03','YYYY-MM-DD')); 
insert into state_data values (7  ,'state_4','x',to_date('2010-12-03','YYYY-MM-DD')); 
insert into state_data values (8  ,'state_2','x',to_date('2010-12-03','YYYY-MM-DD')); 
insert into state_data values (9  ,'state_1','x',to_date('2010-12-03','YYYY-MM-DD')); 
insert into state_data values (10 ,'state_1','x',to_date('2010-12-04','YYYY-MM-DD')); 
insert into state_data values (11 ,'state_2','x',to_date('2010-12-04','YYYY-MM-DD')); 
commit; 

- puis la requête.

select id, state, ref, date1 from (
select id, state, ref, date1, 
     lag(state) over (order by id asc) prev_state 
    from state_data 
) 
where nvl(prev_state,'NULL') != nvl(state,'NULL'); 


     ID STATE    R DATE1 
---------- -------------------- - --------- 
     1 state_1    x 01-DEC-10 
     3 state_2    x 02-DEC-10 
     5 state_1    Y 03-DEC-10 
     6 state_3    x 03-DEC-10 
     7 state_4    x 03-DEC-10 
     8 state_2    x 03-DEC-10 
     9 state_1    x 03-DEC-10 
     11 state_2    x 04-DEC-10 

Le résultat ci-dessus contient des lignes supplémentaires que ce que vous montriez dans la sortie, mais regardant vos données, il semble que cela est le résultat correct.

+0

Merci Rajesh d'avoir pris le temps de répondre et d'affiner cela. Votre solution a bien fonctionné. J'ai juste dû ajouter l'état 'X' ou 'Y'. – tamersalama

+0

Vous êtes les bienvenus:) ... J'ai négligé la partie "x" ..! –