Генерация диапазона дат с использованием SQL - PullRequest
26 голосов
/ 07 января 2009

У меня есть SQL-запрос, который принимает параметр даты (если бы я бросил его в функцию), и мне нужно запускать его каждый день прошлого года.

Как создать список за последние 365 дней, чтобы я мог использовать прямой SQL для этого?

Очевидно, что генерация списка 0..364 тоже подойдет, так как я всегда мог:

SELECT SYSDATE - val FROM (...);

Ответы [ 14 ]

1 голос
/ 11 июля 2018

Лучше поздно, чем никогда. Вот метод, который я разработал (после прочтения этого поста) для возвращения списка дат, который включает: (a) день 1 текущего месяца по сегодняшний день, PLUS (b) все даты за последние два месяца:

select (sysdate +1 - rownum) dt 
from dual 
 connect by rownum <= (sysdate - add_months(sysdate - extract(day from sysdate),-2));

«-2» - это число предыдущих полных месяцев дат, которые необходимо включить. Например, 10 июля этот SQL возвращает список всех дат с 1 мая по 10 июля, то есть два полных предыдущих месяца плюс текущий неполный месяц.

1 голос
/ 07 января 2009

Для забавы вот код, который должен работать в SQL Server, Oracle или MySQL:

SELECT current_timestamp - CAST(d1.digit + d2.digit + d3.digit as int)
FROM 
(
    SELECT digit
    FROM
    (
        select '1' as digit
        union select '2'
        union select '3'
        union select '4'
        union select '5'
        union select '6'
        union select '7'
        union select '8'
        union select '9'
        union select '0'
    ) digits
) d1
CROSS JOIN
(
    SELECT digit
    FROM
    (
        select '1' as digit
        union select '2'
        union select '3'
        union select '4'
        union select '5'
        union select '6'
        union select '7'
        union select '8'
        union select '9'
        union select '0'
    ) digits
) d2
CROSS JOIN
(
    SELECT digit
    FROM
    (
        select '1' as digit
        union select '2'
        union select '3'
        union select '4'
        union select '5'
        union select '6'
        union select '7'
        union select '8'
        union select '9'
        union select '0'
    ) digits
) d3
WHERE CAST(d1.digit + d2.digit + d3.digit as int) < 365
ORDER BY d1.digit, d2.digit, d3.digit -- order not really needed here

Бонусные баллы, если вы можете дать мне кроссплатформенный синтаксис для повторного использования таблицы цифр.

0 голосов
/ 03 декабря 2010

Этот запрос генерирует список дат 4000 дней в будущем и 5000 в прошлом на сегодняшний день (навеяно на http://blogs.x2line.com/al/articles/207.aspx):

SELECT * FROM (SELECT
    (CONVERT(SMALLDATETIME, CONVERT(CHAR,GETDATE() ,103)) + 4000 -
                n4.num * 1000 -
                n3.num * 100 -
                n2.num * 10 -
                n1.num) AS Date, 
    year(CONVERT(SMALLDATETIME, CONVERT(CHAR,GETDATE() ,103)) + 4000 -
                n4.num * 1000 -
                n3.num * 100 -
                n2.num * 10 -
                n1.num) as Year,
    month(CONVERT(SMALLDATETIME, CONVERT(CHAR,GETDATE() ,103)) + 4000 -
                n4.num * 1000 -
                n3.num * 100 -
                n2.num * 10 -
                n1.num) as Month,
    day(CONVERT(SMALLDATETIME, CONVERT(CHAR,GETDATE() ,103)) + 4000 -
                n4.num * 1000 -
                n3.num * 100 -
                n2.num * 10 -
                n1.num) as Day
           FROM (SELECT 0 AS num union ALL
                 SELECT 1 UNION ALL
                 SELECT 2 UNION ALL
                 SELECT 3 UNION ALL
                 SELECT 4 UNION ALL
                 SELECT 5 UNION ALL
                 SELECT 6 UNION ALL
                 SELECT 7 UNION ALL
                 SELECT 8 UNION ALL
                 SELECT 9) n1
               ,(SELECT 0 AS num UNION ALL
                 SELECT 1 UNION ALL
                 SELECT 2 UNION ALL
                 SELECT 3 UNION ALL
                 SELECT 4 UNION ALL
                 SELECT 5 UNION ALL
                 SELECT 6 UNION ALL
                 SELECT 7 UNION ALL
                 SELECT 8 UNION ALL
                 SELECT 9) n2
               ,(SELECT 0 AS num union ALL
                 SELECT 1 UNION ALL
                 SELECT 2 UNION ALL
                 SELECT 3 UNION ALL
                 SELECT 4 UNION ALL
                 SELECT 5 UNION ALL
                 SELECT 6 UNION ALL
                 SELECT 7 UNION ALL
                 SELECT 8 UNION ALL
                 SELECT 9) n3  
               ,(SELECT 0 AS num UNION ALL
                 SELECT 1 UNION ALL
                 SELECT 2 UNION ALL
                 SELECT 3 UNION ALL
                 SELECT 4 UNION ALL
                 SELECT 5 UNION ALL
                 SELECT 6 UNION ALL
                 SELECT 7 UNION ALL
                 SELECT 8) n4
        ) GenCalendar  ORDER BY 1
0 голосов
/ 07 января 2009

У меня нет ответа на повторное использование таблицы цифр, но вот пример кода, который будет работать по крайней мере на SQL-сервере и будет немного быстрее.

print("code sample");

select  top 366 current_timestamp - row_number() over( order by l.A * r.A) as DateValue
from (
select  1 as A union
select  2 union
select  3 union
select  4 union
select  5 union
select  6 union
select  7 union
select  8 union
select  9 union
select  10 union
select  11 union
select  12 union
select  13 union
select  14 union
select  15 union
select  16 union
select  17 union
select  18 union
select  19 union
select  20 union
select  21 
) l
cross join (
select 1 as A union
select 2 union
select 3 union
select 4 union
select 5 union
select 6 union
select 7 union
select 8 union
select 9 union
select 10 union
select 11 union
select 12 union
select 13 union
select 14 union
select 15 union
select 16 union
select 17 union
select 18
) r
print("code sample");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...