powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как обработать ряд дат без использования оконных функций?
17 сообщений из 17, страница 1 из 1
Как обработать ряд дат без использования оконных функций?
    #39484103
X3 кто
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть ряд дат с различными значениями статуса.

Например:

DT STATUS
01.02.2017 1
05.02.2017 2
07.02.2017 2
21.02.2017 3
24.02.2017 1
25.02.2017 3
28.02.2017 2
03.03.2017 1

Необходимо подсчитать общее количество дней для каждого из статусов.

В результате должно получиться следующее:

Для STATUS=1:
с 01.02.2017 по 04.02.2017: 4 дня
с 24.02.2017 по 24.02.2017: 1 день
с 03.03.2017 по 03.03.2017: 1 день
итого: 6 дней

Для STATUS=2:
с 05.02.2017 по 20.02.2017: 16 дней
с 28.02.2017 по 02.03.2017: 3 дня
итого: 19 дней

Для STATUS=3:
с 21.02.2017 по 23.02.2017: 3 дня
с 25.02.2017 по 27.02.2017: 3 дня
итого: 6 дней

Я вполне себе представляю, как это выполнить с помощью “оконных” функций.

А как это сделать без “оконных” функций?
Причём так, чтобы подошло для любой RDBMS.
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484105
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X3 ктоПричём так, чтобы подошло для любой RDBMS.а че тогда подался в етот топик? подруку подвернулся?
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484118
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
на скорую руку
Код: 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.
with x as (
	select date'2017-02-01' dt, 1 status from dual union all
	select date'2017-02-05', 2 from dual union all
	select date'2017-02-07', 2 from dual union all
	select date'2017-02-21', 3 from dual union all
	select date'2017-02-24', 1 from dual union all
	select date'2017-02-25', 3 from dual union all
	select date'2017-02-28', 2 from dual union all
	select date'2017-03-03', 1 from dual
),
whole_interval as (
	select min_dt + level - 1 dt
		from (select min(dt) min_dt, max(dt) max_dt from x)
		connect by min_dt + level - 1 <= max_dt
),
whole_interval_with_statuses as (
	select i.dt,
			(select status
				from (
					select x.status,
							x.dt
						from x
						where x.dt <= i.dt
						order by x.dt desc)
				where rownum = 1) status
		from whole_interval i
)
select count(1)
	from whole_interval_with_statuses i
	group by status

STATUSCOUNT(1)1621936
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484137
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--,

коннект бай распространен еще менее, чем анатилика
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484140
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxконнект бай распространен еще менее, чем анатиликаТС не сказал, что без коннект бая.
а про то, "чтобы подошло для любой RDBMS" - я ему кагбы сразу намекнул
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484145
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уж не знаю, насколько распространена арифметика дат.
И совсем не хотел бы гонять такое по реальной базе.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
with x as (
	select date'2017-02-01' dt, 1 status from dual union all
	select date'2017-02-05', 2 from dual union all
	select date'2017-02-07', 2 from dual union all
	select date'2017-02-21', 3 from dual union all
	select date'2017-02-24', 1 from dual union all
	select date'2017-02-25', 3 from dual union all
	select date'2017-02-28', 2 from dual union all
	select date'2017-03-03', 1 from dual
)
---------------------------------------------------------
select status, sum(days_in_status) as days_in_status
from(
select x1.status
     , coalesce(min(x2.dt), x1.dt+1) - x1.dt as days_in_status
  from x x1 left join x x2 on x1.dt<x2.dt
  group by x1.status, x1.dt
) group by status
order by status
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484226
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X3 кто,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
  1  with x as (
  2     select date'2017-02-01' dt, 1 status from dual union all
  3     select date'2017-02-05', 2 from dual union all
  4     select date'2017-02-07', 2 from dual union all
  5     select date'2017-02-21', 3 from dual union all
  6     select date'2017-02-24', 1 from dual union all
  7     select date'2017-02-25', 3 from dual union all
  8     select date'2017-02-28', 2 from dual union all
  9     select date'2017-03-03', 1 from dual
 10  )
 11  select status,
 12   sum(nvl(((select min(dt) from x x2 where x2.dt>x.dt)-dt),1)) cc
 13  from x
 14* group by status
SQL> /

    STATUS         CC
---------- ----------
         1          6
         2         19
         3          6



.....
stax
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484252
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X3 ктоПричём так, чтобы подошло для любой RDBMS.
Операции с датами тоже должны быть "подходящими для любой RDBMS"?
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484352
rekrabbe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select sum( coalesce( (next_dt - dt), 1) ) as qty,
  status
from 
(
  select status,
    dt,
    lead(dt) over(order by dt) as next_dt
  from x
)
group by status


Ради интереса, как еще можно аналитикой, с помощью keep например?
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484410
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rekrabbe,
first/last value, nth_value

.....
stax
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484816
X3 кто
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
--Eugene--X3 ктоПричём так, чтобы подошло для любой RDBMS.а че тогда подался в етот топик? подруку подвернулся?

А разве есть раздел форума, посвященный языку SQL без привязки к конкретной RDBMS?
Кроме того, львиная доля моего общения с RDBMS посвящена именно ORACLE.
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484830
X3 кто
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
--Eugene--andreymxконнект бай распространен еще менее, чем анатиликаТС не сказал, что без коннект бая.
а про то, "чтобы подошло для любой RDBMS" - я ему кагбы сразу намекнул

Я начал с того, что решил эту задачу с помощью оконных функций.
А с меня потребовали использовать строго SQL92.
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484839
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X3 ктоА с меня потребовали использовать строго SQL92.
Ну тогда:
1. Заводим табличку-календарь.
2. В порядке возрастания дат "с различными значениями статуса" проводим update календаря значением статуса по критерию CALENDAR.DT >= STATUS.DT
3. Повторяем ежедневно для значения статуса >=<текущая дата>.
4. select status, count(*) from calendar where dt <= <текущая дата> group by dt

Вариация: календарь ограничен сверху текущей датой.
Ежедневно в календарь добавляется копия последней (order by dt) записи календаря, помеченная текущей датой.
select status, count(*) from calendar group by dt
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39484862
X3 кто
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymousX3 ктоА с меня потребовали использовать строго SQL92.
Ну тогда:
1. Заводим табличку-календарь.
2. В порядке возрастания дат "с различными значениями статуса" проводим update календаря значением статуса по критерию CALENDAR.DT >= STATUS.DT
3. Повторяем ежедневно для значения статуса >=<текущая дата>.
4. select status, count(*) from calendar where dt <= <текущая дата> group by dt

Вариация: календарь ограничен сверху текущей датой.
Ежедневно в календарь добавляется копия последней (order by dt) записи календаря, помеченная текущей датой.
select status, count(*) from calendar group by dt

А неплохой подход.
Благодарю.
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39485008
coborhc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
X3 кто,

тогда еще проще хранить в исходной таблице кроме даты изменения статуса еще дату след. изменения.
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39485039
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
coborhcтогда еще проще хранить в исходной таблице кроме даты изменения статуса еще дату след. изменения.Это избыточность данных. Сиречь противоречивость.
...
Рейтинг: 0 / 0
Как обработать ряд дат без использования оконных функций?
    #39485667
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eliccoborhcтогда еще проще хранить в исходной таблице кроме даты изменения статуса еще дату след. изменения.Это избыточность данных. Сиречь противоречивость.
иногда избыточность полезна
напр непрерывный диапазон, достаточно даты действует с,
но удобно c избыточностью дата_по=LEAD(dat_from)-"1"

.....
stax
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как обработать ряд дат без использования оконных функций?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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