Как я могу получить таблицу дат с первого дня месяца, два месяца назад, до вчерашнего дня? - PullRequest
3 голосов
/ 29 января 2010

У меня есть ситуация, которую я обычно разрешаю, создав таблицу фидеров (например, каждую дату от пяти лет до столетия в будущем) для запросов, но, к сожалению, эта конкретная работа не позволяет создавать такую ​​таблицу .

Так что я открываю это для SO сообщества. Сегодня 29 января 2010 г. Какой запрос я мог бы выполнить, чтобы получить таблицу с одним столбцом даты со значениями в диапазоне от 1 ноября 2009 г. до 28 января 2010 г. включительно? 1 февраля он должен давать мне каждую дату с 1 декабря 2009 года по 31 января 2010 года.

Я использую DB2, но я рад видеть любые другие решения на случай, если они могут дать подсказку.

Я знаю, что могу выбрать CURRENT DATE из sysibm.sysdummy1 (или dual для тел Oracle), но я не уверен, как сразу выбрать диапазон дат без физической резервной таблицы.

Ответы [ 3 ]

3 голосов
/ 01 февраля 2010

Это просто делает последовательные дни между двумя датами, но я написал, чтобы показать, что вы можете устранить рекурсивную ошибку, указав предел.

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

Обновление от pax:

Этот ответ фактически поставил меня на правильный путь. Вы можете избавиться от предупреждения, введя переменную, ограниченную константой. В приведенном выше запросе он не был вполне правильным (и неправильно указали даты, которые я прощу), но, поскольку он указал мне на решение проблемы, он выиграл приз.

Код ниже был окончательной рабочей версией (без предупреждения):

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;

, который выводится при запуске 2 и февраля:

----------
    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.
0 голосов
/ 29 января 2010

Я раньше не использовал DB2, но в SQL Server вы могли бы сделать что-то вроде следующего. Обратите внимание, что вам нужна таблица с как минимум количеством строк, сколько вам нужно дней.

SELECT TOP 45 
    DATEADD(d, ROW_NUMBER() OVER(ORDER BY [Field]) * -1, GETDATE())
FROM 
    [Table]
0 голосов
/ 29 января 2010

просто идея (даже не знаю, как вы это сделаете), но допустим, вы знали, сколько дней вы хотели. Вроде 45 дней. Если бы вы могли получить выбор к списку 1-45, вы могли бы сделать арифметику дат, чтобы вычесть это число из ваших справочных данных (т.е. сегодня).

Этот вид работает (в MySQL):

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

У меня есть хитрость в том, как заставить 10 быть динамическими. Если вы можете сделать это, то можете использовать такой запрос, чтобы получить правильное число для ограничения.

SELECT DATEDIFF(DATE_SUB(CURDATE(), INTERVAL 1 DAY), 
                DATE_SUB(LAST_DAY(CURDATE()), INTERVAL 2 MONTH))
FROM dual;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...