Игнорирование вашего нечетного использования типов данных *, есть несколько возможных решений:
- Используйте таблицу «календарь», которая содержит даты, и правое соединение с этой таблицей (или левое соединение с этой таблицей),Недостатком, конечно, является необходимость заполнения этой таблицы (но это разовые затраты).
- Используйте выбираемую хранимую процедуру, чтобы создать диапазон дат и присоединиться к нему.
- Создатьдиапазон в рекурсивном общем табличном выражении в самом запросе
Вариант 1 довольно понятен.
Вариант 2 будет выглядеть примерно так:
CREATE OR ALTER PROCEDURE date_range(startdate date, enddate date)
RETURNS (dateval date)
AS
BEGIN
dateval = startdate;
while (dateval <= enddate) do
BEGIN
suspend;
dateval = dateval + 1;
END
END
И затем используйте это в своем запросе, например:
select date_range.dateval, ...
from date_range(date'2019-01-03', date'2019-01-09') -- use date_range(?, ?) for parameters
left join ...
on date_range.dateval = ...
Вариант 3 будет выглядеть примерно так:
WITH RECURSIVE date_range AS (
SELECT date'2019-01-03' dateval -- start date, use cast(? as date) if you need a parameter
FROM rdb$database
UNION ALL
SELECT dateval + 1
FROM date_range
WHERE dateval < date'2019-01-09' -- end date use ? if you need a parameter
)
SELECT *
FROM date_range
LEFT JOIN ...
ON date_range.dateval = ...
Рекурсивные общие табличные выражения имеют максимальную глубину рекурсии 1024, что означает, что онне подходит, если вам нужен промежуток, превышающий 1024 дня.
*: я бы посоветовал вам начать использовать DATE
вместо того, что выглядит как число дней с 30-12-1899.Это избавляет от необходимости делать неловкие вычисления, как вы делаете сейчас.Если вам нужно это количество дней, то вы можете, например, использовать datediff(DAY FROM date'1899-12-30' TO somedatevalue)
или somedatevalue - date'1899-12-30'
для преобразования даты в это числовое значение.