par , 27/11/2022 à 15h03 (342 Affichages)
4e exercice, les chambres libres. De la gestion de planning, j'adooore !
3 problèmes dans cet exercice où on va devoir chercher des choses qui n'existent pas.
A. Les chambres qui sont libres pendant toute la période allant du 11 au 14 janvier 2000
Les chambres occupées étant forcément marquées T_PLANNING_PLN.PLN_LIBRE = False, il suffit donc d'exclure du résultat les chambres présentes en base sur la période et marquées occupées.
Ma solution :
1 2 3 4 5 6 7 8 9
| SELECT ALL CHB_NUM
FROM T_CHAMBRE_CHB
WHERE CHB_NUM NOT IN (
SELECT ALL CHB_NUM
FROM T_PLANNING_PLN
WHERE TRUE
AND PLN_JOUR BETWEEN '2000-01-11' AND '2000-01-14'
AND PLN_LIBRE = 'False'
); |
La jointure externe sera pour plus tard 
B. Occupation des chambres pour la journée du 13 janvier 2000
Ici il faut pour chaque chambre, qu'elle soit présente ou non sur le planning des occupations, donner son occupation. Il faut donc détecter une absence, pour cela rien de mieux qu'une jointure externe.
Ma solution :
1 2 3 4 5 6
| SELECT ALL C.CHB_NUM, COALESCE(P.PLN_LIBRE, 'True') AS PLN_LIBRE
FROM T_CHAMBRE_CHB AS C
LEFT OUTER JOIN T_PLANNING_PLN AS P ON TRUE
AND C.CHB_NUM = P.CHB_NUM
AND P.PLN_JOUR = '2000-01-13'
; |
C. Le planning des occupations pour toutes les chambres et toutes les dates du 11 au 14 janvier 2000
Le jeu de données ne contient des lignes que pour les 12 et 13/01. Il nous manque donc de la data. Intéressant.
S'agissant de seulement 4 dates, on peut simplement les mettre en dur dans une CTE ou une table dérivée (ce que je vais faire). Voire les générer à la volée dans une CTE récursive ou créer une table utilitaire calendar.
Un produit cartésien, obtenu avec CROSS JOIN, permettra de construire nos 2 axes Chambres et Dates, qu'il suffit ensuite de valoriser à l'aide d'une jointure externe.
1 2 3 4 5 6 7
| SELECT ALL CALENDAR.CLD_JOUR, C.CHB_NUM, COALESCE(P.PLN_LIBRE, 'True') AS PLN_LIBRE
FROM T_CHAMBRE_CHB AS C
CROSS JOIN (VALUES ROW ('2000-01-11'), ROW ('2000-01-12'), ROW ('2000-01-13'), ROW ('2000-01-14')) AS CALENDAR (CLD_JOUR)
LEFT OUTER JOIN T_PLANNING_PLN AS P ON TRUE
AND C.CHB_NUM = P.CHB_NUM
AND P.PLN_JOUR = CALENDAR.CLD_JOUR
ORDER BY 1 ASC, 2 ASC; |
Je la trouve belle, cette dernière requête