Bonsoir,
Disons que j'ai une table
Pour chaque sender, je souhaite extraire toutes les lignes ayant le champ valeur différente de la valeur précédente (id est une clé primaire servant aussi pour l'ordre chronologique sur cet exemple)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 CREATE TABLE MaTable ( id BIGINT, sender INT, value SMALLINT );
J'ai une technique via une table intermédiaire et un trigger à l'insertion me permettant de récupérer au fur et à mesure ce résultat... mais je veux aussi avoir une vraie requête performante pour effectuer cette tâche.
Actuellement, en SQL "simple", j'aurais ceci :
Disons que ce n'est clairement pas optimal... je reste donc à la solution du trigger à l'insertion. J'ai également une méthode passant par une table intermédiaire et effectuant un seq scan de MaTable. Rien de très sympa
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 SELECT m.Id as "id",m.sender as "sender" FROM MaTable m WHERE NOT EXISTS ( SELECT m_.Id FROM MaTable m_ WHERE m_.Id<m.Id AND m_.sender=m.sender ) UNION SELECT m1.Id as "id", m1.sender as "sender" FROM MaTable m1, MaTable m2 WHERE m1.sender=m2.sender AND m1.value!=m2.value AND m1.Id>m2.Id AND NOT EXISTS ( SELECT m_.Id FROM main m_ WHERE m2.value!=m_.value AND m_.sender=m1.sender AND m_.Id>m2.Id AND m_.Id<m1.Id ) ORDER BY sender,id
Du coup, en performant, je peux lancer ceci à base de fenêtrage
Je tente ceci
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 SELECT id,sender,value, rank() OVER (PARTITION BY sender ORDER BY id) as "rg" from MaTable ;
Mais je ne vois pas trop comment
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 select tbl.* , nth_value(value,rg-1) over w as "prec" from ( select m.id,m.sender,m.value, rank() over w as "rg" from MaTable m window w as (partition by m.sender order by m.id) ) as tbl ;
EDIT: une astuce
des conseils pour optimiser cela ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 WITH tbl AS ( SELECT m.id,m.sender,me.value, rank() OVER ( PARTITION BY m.sender ORDER BY m.id ) AS "rg", sum(value) OVER ( PARTITION BY m.sender ORDER BY m.id ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING ) as "prec" FROM MaTable m ) SELECT tbl.id FROM tbl WHERE tbl.immo!=tbl.prec
Partager