powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как получить все даты диапазона в столбец
28 сообщений из 28, показаны все 2 страниц
Как получить все даты диапазона в столбец
    #37271340
pixela
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Задача такая:
Запрос выбирает записи из таблицы по диапазону
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
with TAB
as (select date '10.05.2011' COL1,  100  COL2
      from RDB$DATABASE
    union
    select date '15.05.2011' COL1,  150  COL2
      from RDB$DATABASE
    union
    select date '17.05.2011' COL1,  200  COL2
      from RDB$DATABASE)
select *
  from TAB
 where COL1 between date '10.05.2011' and date '20.05.2011'    

Результат запроса:
COL1COL210.05.201110015.05.201115017.05.2011200


Необходимо, чтобы даты, которых нет в таблице тоже присутствовали в результате запроса.
В таком виде:

COL1COL210.05.201110011.05.2011012.05.2011013.05.2011014.05.2011015.05.201115016.05.2011017.05.201120018.05.2011019.05.2011020.05.20110

Как бы мне это реализовать?
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #37271346
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hello, pixela!
You wrote on 20 мая 2011 г. 10:13:24:

pixela> Необходимо, чтобы даты, которых нет в таблице тоже
присутствовали в результате запроса.
то чего нет, заселектить невозможно.
тебе нужен дополнительный объект а-ля "календарь".
динамически формируемый, либо статический - не суть важно.
цепляй его к запросу.

--
With best regards, Мимопроходящий.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #37271394
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну почему же. Можно ещё процедурой и циклом WHILE.
Но правильнее всё же ПРОИЗВОДСТВЕННЫЙ_КАЛЕНДАРЬ LEFT JOIN TAB
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #37271624
pixela
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мимопроходящий, WildSery,

Спасибо за ответ.
Таблицу с календарем была мысль создать, но подумал, что может есть какое-нибудь более интересное решение
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Как получить все даты диапазона в столбец
    #38412164
sidiscom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
подскажите как динамически формировать календарь за указанный период
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412170
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Используя цикл WHILE.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412187
sidiscom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
используя при этом DATEADD(), правильно я понимаю?
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412194
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sidiscomиспользуя при этом DATEADD(), правильно я понимаю?
Достаточно просто прибавлять единичку
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412279
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sidiscomподскажите как динамически формировать календарь за указанный периодЁмкостью до 37 и 5 / 12 лет хватит ?
Если да, то подставляйте стартовую дату вместо '01.01.2000' и ограничивайте числом строк, которое надо.
Код: sql
1.
2.
3.
4.
5.
6.
with recursive
input_arg as (select timestamp '01.01.2000' d from rdb$database)
,n as(select 0 i from rdb$database union all select i+1 from n where i<99)
,n2 as (select n1.i*100+n0.i i from n n1,n n0)
select dateadd(n2.i day to a.d) dates from input_arg a, n2
--order by 1 rows 366
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412486
sidiscom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Таблоидsidiscomподскажите как динамически формировать календарь за указанный периодЁмкостью до 37 и 5 / 12 лет хватит ?
Если да, то подставляйте стартовую дату вместо '01.01.2000' и ограничивайте числом строк, которое надо.
Код: sql
1.
2.
3.
4.
5.
6.
with recursive
input_arg as (select timestamp '01.01.2000' d from rdb$database)
,n as(select 0 i from rdb$database union all select i+1 from n where i<99)
,n2 as (select n1.i*100+n0.i i from n n1,n n0)
select dateadd(n2.i day to a.d) dates from input_arg a, n2
--order by 1 rows 366



Большое спасибо за идею
читая форум в поиске решения данной задачи, получил следующий запрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
with recursive
input_arg as
(select date'20.02.2000' dt1, date '01.03.2000' dt2 from rdb$database),
n as
(select 0 i from rdb$database union all select i+1 from n where i<
(select datediff(day,
   dateadd(month,1-extract(month from dt1),dateadd(day,1-extract(day from dt1),dt1))
  ,dateadd(month,1-extract(month from dt1),dateadd(day,1-extract(day from dt1),dt2))
) i from input_arg))
select dateadd(n.i day to a.dt1) dates from input_arg a, n


прошу высказать свое мнение и возможные вариант оптимизации запроса (я только учусь)
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412510
m_Sla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
execute block
returns  (calendar date)
as
declare start_date date = '01.01.2000';
declare end_date date = current_date;
begin
    calendar=start_date;
    while (calendar <= end_date) do
    begin
        suspend;
        calendar=calendar + 1;
    end
end
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412567
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sidiscomпрошу высказать свое мнение и возможные вариант оптимизации запроса (я только учусь)

Тоже самое, но как по мне гораздо проще для понимания
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
with recursive Input_Arg
as (select date '20.02.2000' Dt1, date '01.03.2000' Dt2
      from Rdb$Database),
N
as (select 0 I
      from Rdb$Database
    union all
    select I + 1
      from N
      where I < (select (Dt2 - Dt1) 
                   from Input_Arg))
select A.Dt1 + N.I Dates
  from Input_Arg A, N     
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412574
sidiscom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
m_Sla
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
execute block
returns  (calendar date)
as
declare start_date date = '01.01.2000';
declare end_date date = current_date;
begin
    calendar=start_date;
    while (calendar <= end_date) do
    begin
        suspend;
        calendar=calendar + 1;
    end
end



Спасибо за вариант, есть вопрос
как в вашем варианте присоединить left join, данные из другой таблице ?
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412576
sidiscom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
m7msidiscomпрошу высказать свое мнение и возможные вариант оптимизации запроса (я только учусь)

Тоже самое, но как по мне гораздо проще для понимания
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
with recursive Input_Arg
as (select date '20.02.2000' Dt1, date '01.03.2000' Dt2
      from Rdb$Database),
N
as (select 0 I
      from Rdb$Database
    union all
    select I + 1
      from N
      where I < (select (Dt2 - Dt1) 
                   from Input_Arg))
select A.Dt1 + N.I Dates
  from Input_Arg A, N     



Спасибо большое. Вариант действительно прост для понимания
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412578
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sidiscom,

вместо блока сделать процедуру и цепляй куда угодно
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412588
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как вариант

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
CREATE EXCEPTION E_INCORRECT_DATE_RAGE '~Дата окончания больше даты начала~';

CREATE OR ALTER PROCEDURE SP_CALENDAR (
    ADATE_BEGIN DATE,
    ADATE_END DATE)
RETURNS (
    BYDATE DATE)
AS
BEGIN
  IF (ADATE_END < ADATE_BEGIN) THEN
    EXCEPTION E_INCORRECT_DATE_RAGE;
  BYDATE = ADATE_BEGIN;
  WHILE (BYDATE < ADATE_END) DO
  BEGIN
    SUSPEND;
    BYDATE = DATEADD(1 DAY TO BYDATE);
  END
END
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412590
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
описался

CREATE EXCEPTION E_INCORRECT_DATE_RANGE '~Дата окончания больше даты начала~';

и

WHILE (BYDATE <= ADATE_END) DO
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412606
sidiscom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денисописался

CREATE EXCEPTION E_INCORRECT_DATE_RANGE '~Дата окончания больше даты начала~';

и

WHILE (BYDATE <= ADATE_END) DO

не хочется использовать процедуру, хотелось все выполнить запросом
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412625
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sidiscom,

тогда вот вариант на мой взгляд более понятный

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
WITH RECURSIVE INPUT_ARG
AS (SELECT DATE '20.02.2000' DATE_BEGIN,
           DATE '01.03.2002' DATE_END
    FROM RDB$DATABASE),
N
AS (SELECT DATE_BEGIN AS BYDATE,
           DATE_END AS DATE_END
    FROM INPUT_ARG
    UNION ALL
    SELECT DATEADD(1 DAY TO BYDATE),
           DATE_END
    FROM N
    WHERE DATEADD(1 DAY TO BYDATE) <= DATE_END)
SELECT BYDATE
FROM N



но у него один существенный минус. Он расчитан всего на 1023 дня из за ограничения на глубину рекурсии
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38412664
afgm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисно у него один существенный минус. Он расчитан всего на 1023 дня из за ограничения на глубину рекурсии
+ Рекурсивный запрос немного выигрывает у процедуры. Сравнение, возможно, не самое корректное:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
with recursive
R(I) as
(
  select 0 from rdb$database
  union all
  select I + 1 from R where I < 1023
)
select count(*) from R R1, R R2


Код: plaintext
Execute time = 608ms
GENERATE_SERIAL
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
create or alter procedure GENERATE_SERIAL (
    FROM_VALUE integer,
    TO_VALUE integer,
    STEP integer = 1)
returns (
    ID integer)
AS
begin
  id = from_value;
  while (id <= to_value) do
  begin
    SUSPEND;
    ID = ID + STEP;
  end
end


Код: sql
1.
2.
3.
4.
with R as (
  select ID from generate_serial(1, 1024)
)
select count(*) from R R1, R R2


Код: plaintext
Execute time = 1s 61ms

Отсутствие опции глубины рекурсии не даёт использовать такие запросы (генераторы последовательностей) на 100%.
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38414627
Евгений Болтик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как то давно, давно в начале изучения SQL, было написано такое. Иногда пользуюсь.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
CREATE PROCEDURE PPeriod (DateFrom date, DateTo date,
Param02 varchar(38),
--0 - 0001 выводить параметр Param02
--1 - 0002 по период
Flags integer)
returns
(num integer,
DMin DATE,
DMax DATE,
Caption varchar(100))
AS
  DECLARE VARIABLE iPeriod INTEGER;
  DECLARE VARIABLE NumPlus INTEGER;
BEGIN
  num = 0;   
  NumPlus = 0;  
  iPeriod = case b_upper(Param02) 
    when b_upper('День') then 1000   
    when b_upper('Неделя') then 5   
    when b_upper('Месяц') then 2   
    when b_upper('Квартал') then 3   
    when b_upper('Полугодие') then 6   
    when b_upper('Год') then 4
    when b_upper('Период') then 0
    else -1
  end;
  
  if (iPeriod >= 0) then begin    
    DateFrom = StartOfThe(DateFrom, iPeriod);
    DateTo = EndOfThe(DateTo, iPeriod);
  end else begin
    NumPlus = B_XNum(Param02);
    if (NumPlus = 0) then NumPlus = 1;
  end
  
  DMin = DateFrom;
  DMax = DateTo;
  if (iPeriod >= 0) then begin  
    if (iPeriod <> 0)
      then DMax = EndOfThe(DMin, iPeriod);
  end else begin
    DMax = DMin+NumPlus-1;
    if (DMax > DateTo) then DateTo = DMax; 
  end
  
  WHILE (DMax <= DateTo) DO BEGIN
    IF (iPeriod = 2) 
      THEN Caption = B_FormatDate('mmm yyyy', DMin);
      ELSE IF (iPeriod = 4) 
      THEN Caption = B_FormatDate('yyyy', DMin);
      ELSE IF (iPeriod = 0) 
      THEN Caption = B_FormatDate('dd.mm.yyyy-', DMin) || B_FormatDate('dd.mm.yyyy', DMax);
      ELSE begin
        Caption = B_FormatDate('dd.mm.yyyy', DMin);
        IF ((b_isbit(Flags, 1) = 1))
           then Caption = Caption || B_FormatDate('-dd.mm.yyyy', DMax);  
      end      
    IF ((iPeriod > 0) and (b_isbit(Flags, 0) = 1))
      then Caption = Caption || coalesce(' (' || Param02 || ')', '');  
    SUSPEND;

    DMin = DMax + 1;
    if (iPeriod >= 0) then begin    
      if (iPeriod = 1000)
        then DMax = EndOfThe(DMin, 0);
        else DMax = EndOfThe(DMin, iPeriod);
    end else begin
      DMax = DMin+NumPlus-1;
    end   
    num = num + 1; 
  END
END
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38414664
Евгений БолтикИногда пользуюсь.В открытом море не взлетает. Мешают наколенники StartOfThe(DateFrom, iPeriod) и EndOfThe(DateTo, iPeriod) (про b_upper не говорю, там всё понятно).
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38414687
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Евгений Болтик,

если все эти UDF есть в базе на FB 2.5 могу только посочувствовать. Давно бы уж на встроенные функции перевёл.
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38414734
Евгений Болтик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ованес СусанянЕвгений БолтикИногда пользуюсь.В открытом море не взлетает. Мешают наколенники StartOfThe(DateFrom, iPeriod) и EndOfThe(DateTo, iPeriod) (про b_upper не говорю, там всё понятно).

Согласен. Могу и их дать, если надо. Вообще как идею единой процедуры на все случаи жизни рассматривали, но так давно что не помню когда.
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38414737
Евгений Болтик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисЕвгений Болтик,

если все эти UDF есть в базе на FB 2.5 могу только посочувствовать. Давно бы уж на встроенные функции перевёл.

Код писался давно. Работает. Голова другим озадачена.
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38414779
Евгений БолтикСогласен. Могу и их дать, если надо.Большое спасибо, но не надо. Отвязались от УДФок еще в 2010, оставили только несколько таких, которые отвечают за форматирование дат и чисел.
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38414818
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ованес Сусанян,

и те можно будет выкинуть в тройке, т.к. можно писать PSQL функции.
...
Рейтинг: 0 / 0
Как получить все даты диапазона в столбец
    #38414836
Симонов Дениси те можно будет выкинуть в тройке, т.к. можно писать PSQL функции.там производительность еще проверять надо. ДЕ говорил, что это еще не пройденная глава (ЕМНИП).
...
Рейтинг: 0 / 0
28 сообщений из 28, показаны все 2 страниц
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как получить все даты диапазона в столбец
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]