Question

J'ai une table mensuelle (contient uniquement les lignes avec le premier jour du mois et une contrainte unique, donc une seule de chaque) et une table journalière contenant des informations similaires pour chaque jour (même transaction, une seule par jour):

Monthly table       Daily table
-------------       -----------
2009-01-01          2009-01-01
2009-02-01          2009-01-02
: :                 : :
2009-09-01          2009-01-31
                    2009-02-01
                    : :
                    2009-02-28
                    2009-03-01
                    : :
                    2009-09-01

mais il peut manquer des jours.

Je souhaite exécuter une requête qui renvoie, pour chaque date de la table mensuelle, cette date ainsi que les dates minimale et maximale de ce mois dans la table journalière (en utilisant le code SQL standard, de préférence spécifique à DB2 si absolument nécessaire).

Donc, si la dernière semaine de janvier et la première semaine de février sont manquantes, il me faut:

MonthStart  FirstDay    LastDay
----------  ----------  ----------
2009-01-01  2009-01-01  2009-01-24
2009-02-01  2009-02-08  2009-02-28
: :
2009-09-01  2009-09-01  2009-01-30

Voici la requête que j'ai:

select m.date as m1,               
       dx.d1 as m2,                          
       dx.d2 as m3                           
from   monthly m,              
       ( select min(d.date) as d1,
                max(d.date) as d2        
         from   daily d            
         where  month(d.date) = month(m.date)
         and    year(d.date) = year(m.date)    
       ) as dx;

mais j'obtiens l'erreur:

  

DSNT408I SQLCODE = -206, ERREUR: M.DATE N'EST PAS UNE COLONNE DE
   TABLE INSERÉE, TABLE MISE À JOUR OU TOUT TABLE IDENTIFIÉE
   DANS UNE CLAUSE DEPUIS OU N'EST PAS UNE COLONNE DE DÉCLENCHEMENT
   TABLEAU DU TRIGGER
   DSNT418I SQLSTATE = 42703 CODE DE RETOUR SQLSTATE

Quelqu'un at-il des conseils sur la meilleure façon de procéder?

Était-ce utile?

La solution

SELECT m.date as m1,               
       MIN(d.date) as m2,                          
       MAX(d.date) as m3
       -- COUNT(d.date) as NbOfDays  -- if so desired...                          
FROM monthly m
JOIN daily d ON month(d.date) = month(m.date) and year(d.date) = year(m.date) 
WHERE -- some condition
GROUP BY m.date
ORDER BY m.date -- or something else...

Notez que ce type de requête (comme les autres présentés dans la question et dans les réponses jusqu'à présent, sont relativement lents, car ils impliquent un balayage de table afin que le mois (x) et l'année (x) puissent être calculés pour chaque élément. [qualifiant] (c’est-à-dire que mettre une plage de dates dans la clause WHERE aiderait bien sûr). Si ce type de requête est exécuté fréquemment et si la taille de la table est importante, il peut être utile d’ajouter un colonne pour ces valeurs calculées (ou éventuellement pour la valeur combinée (Année-Mois), afin que non seulement le calcul ne soit pas nécessaire, mais que les colonnes sous-jacentes puissent être indexées.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top