Database Reference
In-Depth Information
Les.classes.qui.ont.une.sémantique.faible.et.qui.ne.sont.reliées.à.aucune.autre.classe,.à.part.
dans.le.cadre.d'une.association,.sont.en.général.de.bons.exemples.de.classes.qui.ne.doivent.
pas.nécessairement.être.transformées.en.tables.
La question d'une entité DATE (ou parfois NOMBRE ) paraît anodine, mais s'avère
cruciale.
Dans un modèle de données, il devrait toujours igurer une table des dates et une table des
nombres. En effet, un problème important à résoudre dans les requêtes est de retrouver
des données qui ne igurent pas dans la base. Pour cela, il faut artiiciellement créer ces
données pour des ensembles continus. Par exemple, une table des dates sur quelques
siècles. Il devient alors facile et pertinent de retrouver des dates « absentes » des données
de production à l'aide d'une jointure externe droite sur la table des dates. Un exemple
que je donne en démonstration est celui d'un SAV ou je montre une table avec des lignes
d'appareils portés en réparation pendant toute une semaine. J'y omets sciemment un jour,
mettons le mercredi et demande à calculer le nombre moyen d'appareils traités par jour
au cours de cette semaine. La plupart du temps, la requête produite sera fausse, car le
jour absent n'est pas compté !
CREATE TABLE T_SAV (SAV_DATE DATE, SAV_APPAREIL VARCHAR(16));
INSERT INTO T_SAV VALUES
('2011-11-12', 'TV'), ('2011-11-14', 'RADIO'), ('2011-11-12', 'FRIGO'),
('2011-11-13', 'FOUR'), ('2011-11-16', 'RADIO'), ('2011-11-14', 'RADIO'),
('2011-11-12', 'FOUR'), ('2011-11-13', 'FOUR'), ('2011-11-16', 'TV');
requête naïve:
SELECT COUNT(*) / CAST(COUNT(DISTINCT SAV_DATE) AS FLOAT) AS NB_
APPAREIL_PAR_JOUR FROM T_SAV;
NB_APPAREIL_PAR_JOUR
----------------------
2,25
Ce résultat est faux, car la date du 15 novembre 2011 ne igure pas dans la table (peut-être
une grève ?). La solution consiste donc à rajouter une table de date :
CREATE TABLE T_DATE (D DATE);
INSERT INTO T_DATE VALUES ('2011-11-12'), ('2011-11-13'),
('2011-11-14'), ('2011-11-15'), ('2011-11-16');
La requête suivante est correcte :
SELECT COUNT(SAV_APPAREIL) / CAST(COUNT(DISTINCT D) AS FLOAT) NB_
APPAREIL_PAR_JOUR FROM T_SAV
 
Search WWH ::




Custom Search