Inspirée de la requête que j'avais fournie la semaine dernière, en voici une qui gère à présent les chevauchements de périodes :
Le jeu de données pour la tester :
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
19
20
21
22
23 SELECT DISTINCT O1.E, O1.DD , ( -- 3. on identifie la date de fin de la période : SELECT MIN(DF) FROM O O2 WHERE E = O1.E AND DF >= O1.DF AND NOT EXISTS ( SELECT 1 FROM O WHERE E = O2.E AND DD <= O2.DF+1 AND DF > O2.DF)) AS DF -- 1. on balaye la table : FROM O O1 -- 2. on se limite aux lignes dont la date de début -- constitue le début d'une période pour l'établissement concerné : WHERE NOT EXISTS ( SELECT 1 FROM O WHERE E = O1.E AND DF >= O1.DD-1 AND DD < O1.DD);
Le résultat :
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
19 -- On crée la table de périodes d'ouverture O. -- La colonne E indique l'établissement, la colonne DD la date de début, la colonne DF la date de fin CREATE TABLE O (E INTEGER, DD DATETIME, DF DATETIME); INSERT INTO O VALUES (1, '01/01/2001', '03/01/2001'); INSERT INTO O VALUES (1, '04/01/2001', '06/01/2001'); INSERT INTO O VALUES (1, '07/01/2001', '09/01/2001'); INSERT INTO O VALUES (1, '10/01/2005', '11/01/2005'); INSERT INTO O VALUES (1, '10/02/2001', '15/02/2001'); INSERT INTO O VALUES (1, '08/02/2001', '13/02/2001'); INSERT INTO O VALUES (1, '12/02/2001', '18/02/2001'); INSERT INTO O VALUES (1, '20/02/2001', '28/02/2001'); INSERT INTO O VALUES (1, '23/02/2001', '25/02/2001'); INSERT INTO O VALUES (1, '03/03/2001', '09/03/2001'); INSERT INTO O VALUES (1, '03/03/2001', '09/03/2001'); INSERT INTO O VALUES (2, '01/01/2001', '31/12/2009'); INSERT INTO O VALUES (1, '01/01/2004', '03/01/2004'); INSERT INTO O VALUES (1, '01/01/2004', '04/01/2004'); INSERT INTO O VALUES (1, '02/01/2004', '04/01/2004');
La cerise sur le gâteau, ce serait à présent de s'assurer de la cohérence des données de la table O (afin que la requête "travaille" sur des données cohérentes).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 E DD DF 1 01/01/2001 09/01/2001 1 08/02/2001 18/02/2001 1 20/02/2001 28/02/2001 1 03/03/2001 09/03/2001 1 01/01/2004 04/01/2004 1 10/01/2005 11/01/2005 2 01/01/2001 31/12/2009
L'idée est que la date de fin doit être postérieure à la date de début et que les deux doivent être renseignées bien sûr, tout comme l'établissement. Pour cela, deux solutions :
- solution 1 : des contraintes définies lors de la création de la table :
- solution 2 : faire porter la requête, non pas sur la table O, mais sur une vue qui n'en conserve que les données "cohérentes" :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 CREATE TABLE O ( E INTEGER NOT NULL, DD DATETIME NOT NULL, DF DATETIME NOT NULL, CONSTRAINT C1 CHECK (DF>=DD));
Voilà. Bonne fin de week-end à tous.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 SELECT * FROM O WHERE DF>=DD AND E IS NOT NULL;
Partager