Question

I have a monthly table (only holds rows with first day of month, and unique constraint so only one of each) and a daily table with similar information for each day (same deal, only one per day):

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

but there may be days missing.

I want to run a query that returns, for each date in the monthly table, that date along with the minimum and maximum dates for that month in the daily table (using standard SQL preferably of DB2-specific if absolutely necessary).

So, if the last week of January and first week of February is missing, I need:

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

Here's the query I have:

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;

but I'm getting the error:

DSNT408I SQLCODE = -206, ERROR: M.DATE IS NOT A COLUMN OF
AN INSERTED TABLE, UPDATED TABLE, OR ANY TABLE IDENTIFIED
IN A FROM CLAUSE, OR IS NOT A COLUMN OF THE TRIGGERING
TABLE OF A TRIGGER
DSNT418I SQLSTATE = 42703 SQLSTATE RETURN CODE

Does anyone have any advice on how best to do this?

Was it helpful?

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...

Note that this type of query (as the other ones shown in the question and in responses so far, are relatively slow, as they imply a table scan so the month(x) and year(x) can be calculated for each [qualifying] row. (i.e. putting a range on date in the WHERE clause would of course help). If this type of query is ran frequently and if the size of table is significant, it may be useful to add a column for these computed values (or possibly for the combined value (Year-Month), so that not only the calculation is unnecessary but the underlying column(s) can be indexed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top