tags:

views:

104

answers:

3

I have a situation that I would normally solve by creating a feeder table (for example, every date between five years ago and a hundred years into the future) for querying but, unfortunately, this particular job disallows creation of such a table.

So I'm opening this up to the SO community. Today is Jan 29, 2010. What query could I run that would give a table with a single date column with values ranging from Nov 1, 2009 through Jan 28, 2010 inclusive? On Feb 1, it should give me every date from Dec 1, 2009 through Jan 31, 2010.

I'm using DB2 but I'm happy to see any other solutions on the off-chance they may provide a clue.

I know I can select CURRENT DATE from sysibm.sysdummy1 (or dual for Oracle bods) but I'm not sure how to immediately select a date range without a physical backing table.

A: 

just an idea (not even sure how you'd do this), but let's say you knew how many days you wanted. Like 45 days. If you could get a select to list 1-45 you could do date arithmetic to subtract that number from your reference data (ie today).

This kind of works (in MySQL):

set @i = 0; 
SELECT @i:=@i+1 as myrow, ADDDATE(CURDATE(), -@i) 
FROM some_table 
LIMIT 10;

The trick i have is how to get the 10 to be dynamic. If you can do that then you can use a query like this to get the right number to limit.

SELECT DATEDIFF(DATE_SUB(CURDATE(), INTERVAL 1 DAY), 
                DATE_SUB(LAST_DAY(CURDATE()), INTERVAL 2 MONTH))
FROM dual;
mlathe
A: 

Haven't used DB2 before but in SQL Server you could do something like the following. Note that you need a table with at least the number of days that you are going to need.

SELECT TOP 45 DATEADD(d, ROW_NUMBER() OVER(ORDER BY [Field]) * -1, GETDATE()) FROM [Table]

Simon
No shortage of tables with 90 rows in them (sysibm.syscolumns has thousands of the blighters) so I may give this a shot once I find the DB2 equivalents. I'm not sure it has a row_number() equivalent though.
paxdiablo
+1  A: 

This just does sequential days between two dates, but I've posted to show you can eliminate the recursive error by supplying a limit.

with temp (level, seqdate) as 
(select 1, date('2008-01-01')
from sysibm.sysdummy1
union all
select level, seqdate + level days
from temp
where level < 1000 
and seqdate + 1 days < Date('2008-02-01')
)
select seqdate as CalendarDay
from temp
order by seqdate

Update from pax:

This answer actually put me on the right track. You can get rid of the warning by introducing a variable that's limited by a constant. The query above didn't have it quite right (and got the dates wrong, which I'll forgive) but, since it pointed me to the problem solution, it wins the prize.

The code below was the final working version (sans warning):

WITH DATERANGE(LEVEL,DT) AS (
  SELECT 1, CURRENT DATE + (1 - DAY(CURRENT DATE)) DAYS - 2 MONTHS
    FROM SYSIBM.SYSDUMMY1
  UNION ALL SELECT LEVEL + 1, DT + 1 DAY
    FROM DATERANGE
    WHERE LEVEL < 1000 AND DT < CURRENT DATE - 1 DAY
) SELECT DT FROM DATERANGE;

which outputs, when run on the 2nd of February:

----------
    DT
----------
2009-12-01
2009-12-02
2009-12-03
:  :  :  :
2010-01-30
2010-01-31
2010-02-01

DSNE610I NUMBER OF ROWS DISPLAYED IS 63
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL.
BengalTigger
This still has the recursive warning unfortunately. However, by looking into how you (thought you) removed the warning, I was able to nut it out. I've added the code that worked and accepted your answer.
paxdiablo
Glad you worked it out. And, thanks for the correction (and taking it easy on me!)
BengalTigger