SQL-запрос, который возвращает таблицу, где каждая строка представляет дату в заданном диапазоне - PullRequest
0 голосов
/ 03 октября 2008

Можно ли создать запрос SQL, который будет возвращать один столбец, содержащий даты из заданного диапазона дат (например, все даты с прошлого года по сегодняшний день) Э.Г.

dat
----
2007-10-01
2007-10-02
2007-10-03
2007-10-04
...

Мне интересно, возможно ли это в качестве альтернативы созданию таблицы, в которой предварительно вычисляются все эти даты.

Обновлено: Мне нужно решение для MYSQL. Меня не интересуют другие БД в этом случае.

Ответы [ 3 ]

3 голосов
/ 03 октября 2008

AFAIK, вы не можете сделать это с помощью одного запроса SQL. Однако следующий блок кода сделает эту работу.

В настоящее время в Transact-SQL (для SQL Server). Я не знаю, как это переводится на MySQL.

DECLARE @start datetime
DECLARE @end datetime
DECLARE @results TABLE
(
   val datetime not null
)
set @start = '2008-10-01'
set @end = getdate()
while @start < @end
begin
    insert into @results values(@start)
    SELECT @start = DATEADD (d, 1, @start)
end
select val from @results

Это выводит:

2008-10-01 00:00:00.000
2008-10-02 00:00:00.000
2008-10-03 00:00:00.000
2 голосов
/ 03 октября 2008

У меня сейчас нет экземпляра MySQL, но посмотрим, подойдет ли это. Подставьте параметры соответствующим образом. Я жестко закодировал 2007-01-01 для примера.

Привет.

SELECT
    ADDDATE('2007-01-01' INTERVAL SeqValue DAY) DateValue
FROM
(
SELECT
    (HUNDREDS.SeqValue + TENS.SeqValue + ONES.SeqValue) SeqValue
FROM
    (
    SELECT 0  SeqValue
    UNION ALL
    SELECT 1 SeqValue
    UNION ALL
    SELECT 2 SeqValue
    UNION ALL
    SELECT 3 SeqValue
    UNION ALL
    SELECT 4 SeqValue
    UNION ALL
    SELECT 5 SeqValue
    UNION ALL
    SELECT 6 SeqValue
    UNION ALL
    SELECT 7 SeqValue
    UNION ALL
    SELECT 8 SeqValue
    UNION ALL
    SELECT 9 SeqValue
    ) ONES
CROSS JOIN
    (
    SELECT 0 SeqValue
    UNION ALL
    SELECT 10 SeqValue
    UNION ALL
    SELECT 20 SeqValue
    UNION ALL
    SELECT 30 SeqValue
    UNION ALL
    SELECT 40 SeqValue
    UNION ALL
    SELECT 50 SeqValue
    UNION ALL
    SELECT 60 SeqValue
    UNION ALL
    SELECT 70 SeqValue
    UNION ALL
    SELECT 80 SeqValue
    UNION ALL
    SELECT 90 SeqValue
    ) TENS
CROSS JOIN
    (
    SELECT 0 SeqValue
    UNION ALL
    SELECT 100 SeqValue
    UNION ALL
    SELECT 200 SeqValue
    UNION ALL
    SELECT 300 SeqValue
    UNION ALL
    SELECT 400 SeqValue
    UNION ALL
    SELECT 500 SeqValue
    UNION ALL
    SELECT 600 SeqValue
    UNION ALL
    SELECT 700 SeqValue
    UNION ALL
    SELECT 800 SeqValue
    UNION ALL
    SELECT 900 SeqValue
    ) HUNDREDS
) SEQ
WHERE
    SEQ.SeqValue < = 366 AND
    ADDDATE('2007-01-01' INTERVAL SeqValue DAY) < ADDDATE('2007-01-01' INTERVAL 1 YEAR)
ORDER BY
    ADDDATE('2007-01-01' INTERVAL SeqValue DAY) ASC
2 голосов
/ 03 октября 2008

До CTE можно было использовать стандартную предварительно загруженную таблицу целых чисел (обычно несколько тысяч в таблице утилит, см. эту статью ) и присоединяться к ней по мере необходимости. Это будет работать для вас в MySQL:

CREATE TABLE dbo.Numbers 
( 
    Number INT IDENTITY(1,1) PRIMARY KEY CLUSTERED 
) 

WHILE COALESCE(SCOPE_IDENTITY(), 0) <= 1024 
BEGIN 
    INSERT dbo.Numbers DEFAULT VALUES 
END

SELECT DATEADD(dd, Number, DATEADD(dd, 0, DATEDIFF(dd, 0, DATEADD(yy, -1, GETDATE())))) AS Date
FROM Numbers
WHERE Number BETWEEN 0 AND 366

В SQL Server 2005 вы можете использовать общие табличные выражения и рекурсию:

WITH DateRange(Date) AS
(
    SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, DATEADD(yy, -1, GETDATE()))) AS Date
    UNION ALL
    SELECT DATEADD(day, 1, Date) AS Date
    FROM DateRange
    WHERE Date <= GETDATE()
)
SELECT Date 
FROM DateRange
OPTION (MAXRECURSION 366)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...