|
Как сгруппировать записи по дате и еще одному условию? | ☑ | ||
---|---|---|---|---|
0
RomaH
naïve
04.04.22
✎
09:35
|
Есть таблица:
Начало периода - окончание периода - длина слота - количество слотов зачастую начало периода - конец периода в последовательных записях (при сортировке по началу периода) выстраиваются в цепочку как сгруппировать такие записи? https://ibb.co/MRxdyM2 |
|||
1
Вафель
04.04.22
✎
09:41
|
https%3A%2F%2Fprofessorweb.ru%2Fmy%2Fsql-server%2Fwindow-functions%2Flevel3%2F3_11.php
|
|||
2
2mugik
04.04.22
✎
09:43
|
цепляй. Можно наверное какое-нить транзикативное замыкание приплести. На инфостарте иерархию так строить предлагали.
|
|||
3
lEvGl
гуру
04.04.22
✎
09:46
|
что значит сгруппировать, по какому признаку? по часам, или по чем
|
|||
4
_Дайвер_
04.04.22
✎
09:56
|
(3) Как из условий сказано в пределах дня по длине слота, вывести сумму по количеству слотов и выдать дату от и до группируемых строк
|
|||
5
RomaH
naïve
04.04.22
✎
09:57
|
||||
6
lEvGl
гуру
04.04.22
✎
10:12
|
(3) хрен знает, я из другого измерения видимо, из за преломления пространственно временного континуума не вижу таких условий
|
|||
7
Вафель
04.04.22
✎
10:37
|
(6) Задача называется "упаковка интервалов".
довольно таки не тривиальная задача |
|||
8
Ненавижу 1С
гуру
04.04.22
✎
10:45
|
Выберите все начала интервалов, которые не входят в другие полуинтервалы вида (a,b].
Выберите все окончания интервалов, которые не входят в другие полуинтервалы вида [a,b). Соедините их сгруппировав, например по началам интервалов, выбрав минимумы окончаний не меньших этих начал. Применить все это с точностью до других разделителей (пользователей, отделов, других полей) |
|||
9
ДедМорроз
04.04.22
✎
20:15
|
Во-первых,отсортировать по дате начала.
Далее,интервал сравниваем с предыдущим и определяем расстояние,если касаются и перекрываются,то ноль. Ну и запист с нулем объединить с записью,где не ноль,тоже предыдущей. По мойму,не сложно. |
|||
10
vde69
04.04.22
✎
22:20
|
для 1с посмотри в сторону регистров расчета с их "вытеснением"
|
|||
11
ДедМорроз
04.04.22
✎
22:24
|
Вытеснение - это немного не то,это исключение интервала при наложении, а в (0) вопрос про непересекающиеся интервалы.
|
|||
12
vde69
04.04.22
✎
22:27
|
(11)
сначала надо провести вытеснение потом смело объединять все где конец=началу потом повторить сначала, до тех пор пока не исчерпапем все варианты объединения патент довольно известный ("строй и перестраивай"), не думал, что его тут не вспомнят... |
|||
13
Said_We
04.04.22
✎
23:12
|
(0) А что надо сделать с количеством слотов и длинной?
|
|||
14
Said_We
04.04.22
✎
23:15
|
(0) А на рисунке в первом выделении почему выделены строки начиная только с 11:20 до 11:40 ?
Почему не со строки 09:00? |
|||
15
Said_We
04.04.22
✎
23:26
|
(5) Обратите внимание на скорость выполнения с оконными функциями.
Не совсем понял, почему нужно несколько итераций. В оконных функциях есть возможность получать предыдущую строку и следующую. Т.е. для каждой строки можно сразу видеть какое значение следующее и какое предыдущее. Можно лишние строки выкинуть сразу. (6) В чем НЕ тривиальность. В ЗиУП такая задача решается постоянно и без оконных функций. Геморрой, много кода, не быстро работает, но работает. |
|||
16
Said_We
04.04.22
✎
23:33
|
к (14) Увидел. За линией выделения время плохо видно. :-)
Как я понял, то "длина слота" поле группировки, а количество наверное сложить или максимум или минимум или не учитывать. |
|||
17
ДедМорроз
05.04.22
✎
00:08
|
Пересекающиеся интервплы оконной функцией можно обрабатывать,если в наложении приоритет имеет следующий (более поздний по началу интервал) да и то,нужен стек,так как интервал может полностью содержаться в другом,да и количество наложений - величина не постоянная.
Там есть другой способ - все конечные точки в один массив,получаем массив интервалов от одной точки до другой. Для каждого интервала определяем приоритетный отрезок из заданных интервалов,а потом уже снова соединяем последовательные отрезки,если они совпадают. |
|||
18
Said_We
05.04.22
✎
00:09
|
(15) (7) Как пример задачи из ЗиУП. Тут нет даты окончания, но переделать запрос не сложно, условие дополнить сравнением даты начала и окончания периода...
+ В примере (0) дата+время, а не просто дата. Так как есть дата конца периода всегда, не нужно вычислять дату окончания. with data as (Select '2017-01-10' as d, 'rabotaet' as s union all select '2017-02-23', 'rabotaet' union all select '2017-02-28', 'otpusk' union all select '2017-03-11', 'bolnichniy' union all select '2017-03-15', 'bolnichniy' union all select '2017-03-17', 'bolnichniy' union all select '2017-03-30', 'rabotaet' union all select '2017-04-02', 'rabotaet' union all select '2017-04-08', 'otpusk' union all select '2017-04-14', 'rabotaet' union all select '2017-04-28', 'uvolen' ) select t.d as dateN ,Cast(DateADD(day, -1, LEAD(t.d) OVER(ORDER BY t.d)) as date) dateK ,t.s from (select t.d ,t.s ,LAG(t.s) OVER(ORDER BY t.d) prev_s from data as t ) as t where t.s <> t.prev_s or t.prev_s is null -------------------------------- * with - генерация данных, по существу создание временной таблицы. В 1С аналог "ПОМЕСТИТЬ". * LAG() предыдущая запись * LEAD() следующая запись -------------------------------- В 1С, так как нет оконных функций, то предыдущую запись и следующую надо получать LEFT JOIN таблицы саму с собой. Что бы проще это было делать, то можно предварительно добавить поле Автонумирации и по нему соединение строить. Выбрать первые 99999999 т.*, row_number() ПОМЕСТИТЬ ВТ_Данные из ВТ как т Упорядочить по ... |
|||
19
Said_We
05.04.22
✎
00:12
|
(17) В задаче (0) нет пересекающихся периодов. Считай декомпозицию уже сделали и разбили на максимальное количество периодов. Далее в (0) как раз уже схлопнуть периоды.
|
|||
20
Said_We
05.04.22
✎
12:47
|
(0) А что надо сделать с количеством слотов?
С длиной вроде понятно - группировка/разрез это. |
|||
21
RomaH
naïve
05.04.22
✎
12:48
|
(20) - сложить
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |