Citation Envoyé par J1 Voir le message
@SQLpro : la règle de gestion sous-entendue par gontrand16 ne s'intéresse qu'aux périodes qui se succèdent strictement (DD=DF+1), mais il serait en effet intéressant de gérer des chevauchements de périodes. A étudier à l'occasion.
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 :

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 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
 
-- 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');
Le résultat :
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
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).
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 :
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));
- 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
 
SELECT * 
FROM O 
WHERE DF>=DD
AND E IS NOT NULL;
Voilà. Bonne fin de week-end à tous.