powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Сгруппировать записи по дате в диапазоне 10 сек.
25 сообщений из 30, страница 1 из 2
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643115
rigor mortis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет,
что-то затруднился. Есть выборка, нужно сгруппировать по дате таким образом, чтобы даты в пределах 10 сек попали в одну группу, то есть должно получиться 3 группы

iddate1 27.07.10 08:25:15 --группа 11 14.05.14 07:06:29 --группа 21 26.02.18 09:43:21 --группа 31 26.02.18 09:43:23 --группа 31 26.02.18 09:43:25 --группа 31 26.02.18 20:43:25 --группа 4

кто-нибудь знает как это сделать?
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643118
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortis,

match_recognize
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643122
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortis,

А что являеться стартовым временем для группы?
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643132
rigor mortis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MaximaXXL, минимальная дата группы.
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643136
123йй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortis,

26.02.18 23:59:55 и 27.02.18 00:00:03
в одной группе ?
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643142
rigor mortis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
123йй, да
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643148
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortis,

Я не очень понимаю, можешь расставить группы?
09:14:52
09:15:01
09:15:02
09:15:03
09:15:05
09:15:07
09:15:09
09:15:11
09:15:12
09:15:13
09:15:14
09:15:15
09:15:23
09:15:24
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643159
j2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortis, А если бы вместо 26.02.18 09:43:25 было бы 26.02.18 09:43:26 это была бы новая группа?
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643225
Фотография шК0ДЕР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТС имеет в виду, что все группирование начинается с первой даты. Все что входит в "первая дата + 10 сек" - первая группа, +20 сек - вторая группа и т.д.
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643234
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
шК0ДЕРТС имеет в виду, что все группирование начинается с первой даты. Все что входит в "первая дата + 10 сек" - первая группа, +20 сек - вторая группа и т.д.
Решение в Вашей интерпретации тривиально.

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

+1с
+2с
+9с

+19с
+21с
+28с

+35с
+44с

Решение в таком сценарии возможно как через sog, так и посредством match_recognize
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643250
rigor mortis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не, тут скорее так. Все записи grooup by date. Идём начиная с первой записи:
Дата текущей записи становится group_start_date и если текущая дата <= group_start_date + 10 сек. то это группа 1.
Иначе дата текущей записи становится group_start_date и это уже группа 2 и заново: если group_start_date <= первая + 10 сек. то это группа 2.
и т. д.
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643253
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortis group_start_date и это уже группа 2 и заново: если group_start_date <= первая + 10 сек. то это группа 2.
и т. д.
До 12с: ищите по форуму метод "start_of_group", примеров обильно.
12с: именно под подобные задачи введен match_recognize
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643287
j2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortisНе, тут скорее так. Все записи grooup by date.
тогда мне непонятно почему:
123ййrigor mortis,
26.02.18 23:59:55 и 27.02.18 00:00:03
в одной группе ?
rigor mortis123йй, да
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643325
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortisИдём начиная с первой записи:
Дата текущей записи становится group_start_date и если текущая дата <= group_start_date + 10 сек. то это группа 1.
Иначе дата текущей записи становится group_start_date и это уже группа 2 ...Получается, если sysdate больше минимальной даты в таблице, то группы нумеруются с 2 и приведенные в первом посте данные "группа 1" неверны.
Остального, кто на ком стоял, не понял.
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643350
123йй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortis,
Код: plsql
1.
case when d-lag(d,1,d-1) over (order by d)<10/60/60/24 then 0 else 1 end sog


типа такого ?
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643360
lsd-super
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
with t as
(select to_date(regexp_substr(txt, '([^[:space:]]+)', 1, level),
'hh24:mi:ss') time_
FROM (SELECT '09:14:52
09:15:01
09:15:02
09:15:03
09:15:05
09:15:07
09:15:09
09:15:11
09:15:12
09:15:13
09:15:14
09:15:15
09:15:23
09:15:24' AS txt
FROM dual)
CONNECT BY level <= regexp_count(txt, '([[:space:]]+)') - 1),
tt as
(select to_date('00:00:00', 'hh24:mi:ss') + (level - 1) * 10 / 86400 begin_

from dual
connect by level - 1 <= 8639)

select distinct to_char(begin_, 'hh24:mi:ss') begin_,
to_char(begin_ + 10 / 86400, 'hh24:mi:ss') end_,
count(1) over(partition by begin_) c_
from t, tt
where time_ between tt.begin_ and begin_ + 10 / 86400
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643380
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortisНе, тут скорее так. Все записи grooup by date. Идём начиная с первой записи:
Дата текущей записи становится group_start_date и если текущая дата <= group_start_date + 10 сек. то это группа 1.
Иначе дата текущей записи становится group_start_date и это уже группа 2 и заново: если group_start_date <= первая + 10 сек. то это группа 2.
и т. д.
если < 12-ки

я б делал через рекурсивный with по описаному сценарию,
Идём начиная с первой записи и ...

....
stax
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643392
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
-- Тестовые данные
with t(id, dt) as ( select 1, to_date('27.07.10 08:25:15','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('14.05.14 07:06:29','dd.mm.rr hh24:mi:ss')
from dual union all select 1, to_date('26.02.18 09:43:21','dd.mm.rr hh24:mi:ss')
from dual union all select 1, to_date('26.02.18 09:43:23','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('26.02.18 09:43:25','dd.mm.rr hh24:mi:ss')
from dual union all select 1, to_date('26.02.18 20:43:25','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('26.02.18 20:43:27','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('26.02.18 20:43:29','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('26.02.18 20:43:31','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('26.02.18 20:43:33','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('26.02.18 20:43:35','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('26.02.18 20:43:37','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('26.02.18 20:43:39','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('26.02.18 20:43:41','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('26.02.18 20:43:58','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('26.02.18 20:44:07','dd.mm.rr hh24:mi:ss') 
from dual union all select 1, to_date('26.02.18 20:44:08','dd.mm.rr hh24:mi:ss') 
from dual)
----------------------------------------------

with --<исходные данные порезаны>
, tt as (
select t.id, t.dt
     , case when dt-lag(dt) over(partition by id order by dt) <= 10/86400 then null else dt end group_base_dt
from t
)
select tt.id, tt.dt
     , max(group_base_dt) over(partition by id order by dt) group_start_date -- группа (дата)
     , trunc(86400*(dt-max(group_base_dt) over(partition by id order by dt)),-1) group_offset_10 -- подгруппа(10-сек. смещение) в группе
from tt
order by id, dt
;

--12с:
with --<исходные данные порезаны>
select * from t
match_recognize(
  partition by id
  order by dt
  measures leader.dt as g_id
  all rows per match
  pattern (leader follower*)
  define follower as follower.dt-leader.dt < 10/86400
)
order by id, dt
;
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643395
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous
Код: plsql
1.
  measures leader.dt as g_id

match_number()
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643400
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-andrey_anonymous
Код: plsql
1.
  measures leader.dt as g_id

match_number()
Я специально сделал так, как сделал
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643442
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
with t(id, dt) as ( select 1, to_date('08:25:00','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:07','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:16','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:20','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:21','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:22','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:23','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:25','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:26','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:34','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:39','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:40','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:41','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:42','hh24:mi:ss') 
from dual union all select 1, to_date('08:25:43','hh24:mi:ss') 
from dual) 


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
ID	DT	GROUP_START_DATE	GROUP_OFFSET_10
1	08:25:00	08:25:00	0
1	08:25:07	08:25:00	0
1	08:25:16	08:25:00	10
1	08:25:20	08:25:00	10
1	08:25:21	08:25:00	20
1	08:25:22	08:25:00	20
1	08:25:23	08:25:00	20
1	08:25:25	08:25:00	20
1	08:25:26	08:25:00	20
1	08:25:34	08:25:00	30
1	08:25:39	08:25:00	30
1	08:25:40	08:25:00	40
1	08:25:41	08:25:00	40
1	08:25:42	08:25:00	40
1	08:25:43	08:25:00	40

ps
считая match_recognize за правило

.....
stax
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643448
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax
Код: plaintext
1.
2.
3.
4.
ID	DT	GROUP_START_DATE	GROUP_OFFSET_10
1	08:25:16	08:25:00	10
1	08:25:20	08:25:00	10



Вот так должно быть поровнее, 20-я секунда в примере уедет в подгруппу +20, где ей и место.
Код: plsql
1.
     , floor(86400*(dt-max(group_base_dt) over(partition by id order by dt))/10)*10 group_offset_10 -- подгруппа(10-сек. смещение) в группе



Но это детали.
Основная идея в следующем: если добавить к примеру
Код: plsql
1.
2.
3.
4.
from dual union all select 1, to_date('08:30:45','hh24:mi:ss') 
from dual union all select 1, to_date('08:30:54','hh24:mi:ss') 
from dual union all select 1, to_date('08:30:55','hh24:mi:ss') 
from dual union all select 1, to_date('08:30:57','hh24:mi:ss') 


то образуются 10-секундные периоды 08:30:45-08:30:54 и 08:30:55-08:31:04, т.е. интервал формируется от лидера группы.

Для общего усложнения смысла жизни можно выразиться так:
Код: plsql
1.
2.
     , max(group_base_dt) over(partition by id order by dt) 
     + floor(86400*(dt-max(group_base_dt) over(partition by id order by dt))/10)*10/86400 group_start_date -- группа (дата)



но мне показалось, что это будет сложно осознать без алкоголя и я не стал публиковать :)
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643461
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousStax
Код: plaintext
1.
2.
3.
4.
ID	DT	GROUP_START_DATE	GROUP_OFFSET_10
1	08:25:16	08:25:00	10
1	08:25:20	08:25:00	10



Вот так должно быть поровнее, 20-я секунда в примере уедет в подгруппу +20, где ей и место.
Код: plsql
1.
     , floor(86400*(dt-max(group_base_dt) over(partition by id order by dt))/10)*10 group_offset_10 -- подгруппа(10-сек. смещение) в группе



Но это детали.
Основная идея в следующем: если добавить к примеру
Код: plsql
1.
2.
3.
4.
from dual union all select 1, to_date('08:30:45','hh24:mi:ss') 
from dual union all select 1, to_date('08:30:54','hh24:mi:ss') 
from dual union all select 1, to_date('08:30:55','hh24:mi:ss') 
from dual union all select 1, to_date('08:30:57','hh24:mi:ss') 


то образуются 10-секундные периоды 08:30:45-08:30:54 и 08:30:55-08:31:04, т.е. интервал формируется от лидера группы.

Для общего усложнения смысла жизни можно выразиться так:
Код: plsql
1.
2.
     , max(group_base_dt) over(partition by id order by dt) 
     + floor(86400*(dt-max(group_base_dt) over(partition by id order by dt))/10)*10/86400 group_start_date -- группа (дата)



но мне показалось, что это будет сложно осознать без алкоголя и я не стал публиковать :)

немного не понял
Код: 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 t(id, dt) as ( select 1, to_date('08:25:00','hh24:mi:ss')   
from dual union all select 1, to_date('08:25:07','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:16','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:20','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:21','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:22','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:23','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:25','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:26','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:34','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:39','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:40','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:41','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:42','hh24:mi:ss')  
from dual union all select 1, to_date('08:25:43','hh24:mi:ss')  
from dual)  
----------------------------------------------  
, tt as (  
select t.id, t.dt  
     , case when dt-lag(dt) over(partition by id order by dt) <= 10/86400 then null else dt end group_base_dt  
from t  
)  
select tt.id, tt.dt  
     --, max(group_base_dt) over(partition by id order by dt) group_start_date -- группа (дата)  
      , max(group_base_dt) over(partition by id order by dt) 
     + floor(86400*(dt-max(group_base_dt) over(partition by id order by dt))/10)*10/86400 group_start_date
     --, trunc(86400*(dt-max(group_base_dt) over(partition by id order by dt)),-1) group_offset_10 -- подгруппа(10-сек. смещение) в группе  
     , floor(86400*(dt-max(group_base_dt) over(partition by id order by dt))/10)*10 group_offset_10 
from tt  
order by id, dt


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
ID	DT	GROUP_START_DATE	GROUP_OFFSET_10
1	08:25:00	08:25:00	0
1	08:25:07	08:25:00	0
1	08:25:16	08:25:10	10
1	08:25:20	08:25:20	20
1	08:25:21	08:25:20	20
1	08:25:22	08:25:20	20
1	08:25:23	08:25:20	20
1	08:25:25	08:25:20	20
1	08:25:26	08:25:20	20
1	08:25:34	08:25:30	30
1	08:25:39	08:25:30	30
1	08:25:40	08:25:40	40
1	08:25:41	08:25:40	40
1	08:25:42	08:25:40	40
1	08:25:43	08:25:40	40

вторая группа начинается на 16 сек и должна продолжатся до 25(26) сек

считаю что для match_recognize правильно
и другие решения должны повторить результат

.....
stax
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643462
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Stax]andrey_anonymousпропущено...
немного не понял

Я в варианте с аналитикой решил, что достаточно начать формирование непрерывного интервала от простоя >10 сек, каковой разбить на 10-секундные подинтервалы.
Staxвторая группа начинается на 16 сек и должна продолжатся до 25(26) сек

Ну может и так.
Только аналитикой это будет, КМК, совсем сложно сделать - проще pipelined прикруить.
Хотя... Одна идейка, возможно, есть. Но уже не сегодня - если руки дойдут.
...
Рейтинг: 0 / 0
Сгруппировать записи по дате в диапазоне 10 сек.
    #39643485
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousТолько аналитикой это будет, КМК, совсем сложно сделать - проще pipelined прикруить.
Хотя... Одна идейка, возможно, есть. Но уже не сегодня - если руки дойдут.
просим, просим.
не троллинга ради, но познания для (можно даже не отвечать, если что)
...
Рейтинг: 0 / 0
25 сообщений из 30, страница 1 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Сгруппировать записи по дате в диапазоне 10 сек.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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