Elément précédent

La norme SQL évolue : tirez le meilleur d'un SGBD qui la respecte en écrivant du SQL moderne avec en complément PL/pgSQL, php, java etc.
Répondre
Phil
Administrateur du site
Messages : 248
Enregistré le : mar. 1 sept. 2015 00:38
Localisation : France
Contact :

Elément précédent

Message par Phil » lun. 9 sept. 2019 14:29

Merci à Bruno pour sa question :

"Dans la table des "RUMS" on peut avoir plusieurs lignes pour un "RSSS", chaque "RUM" a une date de début différente, exemple :

Code : Tout sélectionner

RUMS_ID	RUMS_ID_RSSS	RUMS_DATE_DEBUT		VALEUR
1       2		2015-10-06		F
3       2		2015-11-06		F
4       2		2015-12-06		V
11      3		2016-11-22		F
12      3		2016-11-24		F
Je voudrais faire une requête qui pour chaque RUM d’un RSSS donne toutes les infos du RUM plus l’ID du RUM précédent et j'ai écrit ça :

Code : Tout sélectionner

select p.rums_id RUMS_ID_PREC, r.*
from act_dim_rums r, act_dim_rums p
where p.rums_id_rsss = r.rums_id_rsss
and p.rums_date_debut = (select max(p2.rums_date_debut) from act_dim_rums p2 where p2.rums_id_rsss = r.rums_id_rsss and p2.rums_date_debut < r.rums_date_debut);
Problème : ce SQL ne sélectionne pas le 1er RUM car il n’a pas de précédent (ben oui, logique, c’est le 1er) … comment faire pour qu’il affiche quand même le 1er RUM, avec le RUMS_ID_PREC à null ?"

Réponse :

Il serait possible de modifier la requête proposée mais je préfère une approche analytique pour une telle requête.

Exemple :

Code : Tout sélectionner

select version();
                                                    version
----------------------------------------------------------------------------------------------------------------
 PostgreSQL 11.5 (Debian 11.5-1+deb10u1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit


create table act_dim_rums(rums_id int, rums_id_rsss int, rums_date_debut date, valeur boolean);
CREATE TABLE

insert into act_dim_rums(rums_id, rums_id_rsss, rums_date_debut, valeur) 
values
(1, 2, '2015-10-06', false),
(3, 2, '2015-11-06', false),
(4, 2, '2015-12-06', true),
(11, 3, '2015-11-22', false),
(12, 3, '2015-11-24', false);
INSERT 0 5

SELECT lag(rums_id) OVER (PARTITION BY rums_id_rsss ORDER BY rums_date_debut ASC) RUMS_ID_PREC, r.* from act_dim_rums r;

 rums_id_prec | rums_id | rums_id_rsss | rums_date_debut | valeur
--------------+---------+--------------+-----------------+--------
              |       1 |            2 | 2015-10-06      | f
            1 |       3 |            2 | 2015-11-06      | f
            3 |       4 |            2 | 2015-12-06      | t
              |      11 |            3 | 2015-11-22      | f
           11 |      12 |            3 | 2015-11-24      | f
Cdlt. Phil - pgphil.ovh

Phil
Administrateur du site
Messages : 248
Enregistré le : mar. 1 sept. 2015 00:38
Localisation : France
Contact :

Elément suivant

Message par Phil » mer. 18 sept. 2019 10:20

Merci à Bruno pour son suivi :

D'accord, ça marche. Si je veux en plus l'élément suivant sur la même ligne, je fais comme ça ?

Code : Tout sélectionner

SELECT 
lag(rums_id) OVER (PARTITION BY rums_id_rsss ORDER BY rums_date_debut ASC) RUMS_ID_PREC, 
lag(rums_id) OVER (PARTITION BY rums_id_rsss ORDER BY rums_date_debut DESC) RUMS_ID_SUIV, 
r.* from act_dim_rums r;

Réponse :

Cela fonctionnerait mais je suggère d'utiliser lorsque c'est possible la même fenêtre afin d'optimiser :

Code : Tout sélectionner

select version();
                                                    version
----------------------------------------------------------------------------------------------------------------
 PostgreSQL 11.5 (Debian 11.5-1+deb10u1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit

SELECT 
lag(rums_id) OVER (PARTITION BY rums_id_rsss ORDER BY rums_date_debut ASC) RUMS_ID_PREC, 
lead(rums_id) OVER (PARTITION BY rums_id_rsss ORDER BY rums_date_debut ASC) RUMS_ID_SUIV, 
r.* from act_dim_rums r;
Cdlt. Phil - pgphil.ovh

Répondre