Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите с группировкой по времени / 11 сообщений из 11, страница 1 из 1
23.12.2014, 11:45:06
    #38840397
GibsonG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с группировкой по времени
Здравствуйте! К сожалению с postgre только начал разбираться т.к. понадобились пространственные типы данных и столкнулся с некоторыми сложностями в запросах и очень нужна ваша помощь.


1. задача нужно сгруппировать записи по промежутку времени.
К примеру есть ряд записей у которых промежуток между временем 5-10 секунд, а есть более часа.
Нужно как-то сгруппировать данные промежуток между которых менее минуты.

2. задача так же со временем.
Так же есть точки добавляемые раз в 5 секунд. Но между ними могут быть промежутки в часы.
Нужно выбрать все точки между которыми меньше минуты промежуток.

Вот пример: мобильное устройство шлет координаты и едет по маршруту. Мне нужно по сути собрать все точки за определенный промежуток времени (к примеру месяц) и дальше уже делать расчеты. То бишь отрезки где больше минуты мне считать не нужно.

Выбирать кучу данных и считать на PHP это тупость, нужно делать это как-то на уровне SQL
Помогите пожалуйста, голова уже идет кругом. заранее спасибо.
...
Рейтинг: 0 / 0
24.12.2014, 00:11:31
    #38841155
Ivan Durak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с группировкой по времени
1. Округли дату до минуты и группируй. как - http://postgresql.ru.net/node/214418
2. не понял что надо - пример чтоли придумай
...
Рейтинг: 0 / 0
24.12.2014, 11:16:53
    #38841441
NikolayV81
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с группировкой по времени
GibsonGЗдравствуйте! К сожалению с postgre только начал разбираться т.к. понадобились пространственные типы данных и столкнулся с некоторыми сложностями в запросах и очень нужна ваша помощь.


1. задача нужно сгруппировать записи по промежутку времени.
К примеру есть ряд записей у которых промежуток между временем 5-10 секунд, а есть более часа.
Нужно как-то сгруппировать данные промежуток между которых менее минуты.

2. задача так же со временем.
Так же есть точки добавляемые раз в 5 секунд. Но между ними могут быть промежутки в часы.
Нужно выбрать все точки между которыми меньше минуты промежуток.

Вот пример: мобильное устройство шлет координаты и едет по маршруту. Мне нужно по сути собрать все точки за определенный промежуток времени (к примеру месяц) и дальше уже делать расчеты. То бишь отрезки где больше минуты мне считать не нужно.

Выбирать кучу данных и считать на PHP это тупость, нужно делать это как-то на уровне SQL
Помогите пожалуйста, голова уже идет кругом. заранее спасибо.

Не совсем понял, интервалы переменной длины?
т.е. к примеру ваше значение 1 мин.

00:00 - 1
01:40 - 2
01:45 - 3
02:39 - 4
02:41 - 5
03.42 - 6
вам нужно ( ( 1 ), ( 2,3,4,5 ), ( 6 ) ) или ( ( 1 ), ( 2,3,4 ), ( 5 ), (6) )?

если вариант 1 то серверной процедурой, по другому не стоит.
...
Рейтинг: 0 / 0
24.12.2014, 11:17:56
    #38841443
NikolayV81
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с группировкой по времени
NikolayV81,

или вариант 3:
( ( 1 ), ( 2, 3 ), ( 4, 5 ), (6 ) )?
...
Рейтинг: 0 / 0
24.12.2014, 17:19:32
    #38841968
Помогите с группировкой по времени
GibsonG,

Почитай про оконные функции. В частности про LEAD / LAG.
...
Рейтинг: 0 / 0
24.12.2014, 17:21:57
    #38841974
Помогите с группировкой по времени
GibsonG,

Как вариант - пошерсти оракловую ветку форума по слову start_of_group , чтобы понять, как к твоей задаче прикрутить LEAD / LAG
...
Рейтинг: 0 / 0
29.12.2014, 15:38:53
    #38845765
GibsonG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с группировкой по времени
Извините что долго не отвечал. отвлекли по работе.

В общем постараюсь объяснить на одном из примеров более подробно.

По маршруту идет машина (полилиния). Если к примеру машина ушла с машрута я нахожу все точки не принадлежащие к маршруту.

время может быть такое

(первый уход)
2014-12-28 16:10:05
2014-12-28 16:10:10
2014-12-28 ---
2014-12-28 16:20:30

(второй уход)
2014-12-28 16:10:05
2014-12-28 16:10:10
2014-12-28 ---
2014-12-28 16:20:30

к примеру мне нужно посчитать кол-во уходов и время ухода.
То бишь тут нужны первые значения. сгрупированные по отрезкам.
Можно конечно выгрузить все в PHP и там искать, но это не есть хорошо.

Другой пример аналогичная ситуация, только выбирается не уход с маршрута а вхождение в какой-то полигон (многоугольник)

Добрый Э - Эх - да я немного читал про оконные функции, но прям сходу не смог понять как сгруппировать. С оконными не работал. Все что понял это выполнение агрегатных функций для каждой записи.

А уже далее по этим данным можно сгруппировать.
Буду читать дальше, спасибо за уточнение
...
Рейтинг: 0 / 0
29.12.2014, 16:56:18
    #38845876
Помогите с группировкой по времени
GibsonG,

приведи юзабельный набор репрезентативных тестовых данных и желаемый результат на них, и желающих помочь в написании запроса резко увеличится...
...
Рейтинг: 0 / 0
05.01.2015, 21:56:12
    #38848684
Electric200
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с группировкой по времени
Ах... прям читаю и себя вижу годик назад. ))))
1. PHP нет не нужно.
2. PL/PgSQL вам в помощь, потому как поддерживает нативные типы данных.
3. Прохождение по всем записям. FOR rec IN "QUERY". И дальше IF (a-b)<1 минут THEN фиксируем начало отрезка ELSE фиксируем конец отрезка. Здесь можно много еще условий вставить, которые вам понадобятся в будущем (поверьте на слово). Это и количество координат можно ограничивать, и время общее просчитать и количество отрезков и кучу всего остального.
Можно конечно под каждую задачу запрос писать. Но без постагрегации данных - не обойтись.Та и в запросе без агрегаторов, разных CASE WHEN и тех же окон - не обойтись. А если запросы динамические на 70% то вам придется их готовить за базой, в том же PHP. И это лишает вас одного преимущества. Или даже двух. Кеширования планов и использования компилированых процедур.
В общем, я бы не советовал создавать абрукадабру в виде запросов и размазывать бизнес логику между слоями приложения под такие задачи. Потому как ожидаемого прироста скорости это не даст в итоге. А PLPG и тот же PostGis со своими Geometry,WithIN и другими плюшками у вас всегда под рукой.
Только одно но! Разбивайте такие запросами порциями (по времени или количеству координат). Любая конкатенация varchar внутри хранимки в цикле - зло. Простые арифметические операции летают. Ну и конечно же индексы, изучайте род и планы своих запросов. В общем Postgres ням ням... а сегодня еще PgBouncer прикрутил - не могу нарадоваться)))
...
Рейтинг: 0 / 0
12.01.2015, 05:41:21
    #38851868
hattifattener
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с группировкой по времени
GibsonGПо маршруту идет машина (полилиния). Если к примеру машина ушла с машрута я нахожу все точки не принадлежащие к маршруту.


Тогда выходит все несколько хитрее - если машина на одну точку отклонилась а на следующей вернулась, то это считается отдельным уходом? А какой длительности?

Я бы предложил для начала определить критерий принадлежности точки маршруту, затем отселектить последовательно ВСЕ точки с отдельной колонкой - признаком принадлежности (булевым). Должно получиться что-то вроде

moment | geodata | online
-----------------------------------------------
2014-12-28 16:10:05 | ....... | true
2014-12-28 16:10:10 | ....... | true
2014-12-28 16:10:15 | ....... | false
2014-12-28 16:10:20 | ....... | false
2014-12-28 16:10:25 | ....... | true
2014-12-28 16:10:30 | ....... | false
2014-12-28 16:10:35 | ....... | false
2014-12-28 16:10:40 | ....... | false
2014-12-28 16:10:45 | ....... | true

Для первого ухода интервал по идее должен быть 16:10:15 ... 16:10:25

Обработать это окнами может и можно, но имхо черезушно. Проще прогнать через функцию ( tstart out timestamp, tend out timestamp ), в которой что-то вроде
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
flag := true;
for r in select ..... loop
if flag and not r.online then
tstart := r.moment;
end if;
if not flag and r.online then
tend := r.moment;
return next;
end if;
flag := r.online;
end loop;
...
Рейтинг: 0 / 0
12.01.2015, 06:06:16
    #38851870
hattifattener
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с группировкой по времени
UP: Если же соблюдать рассовую чистоту SQL, то получится что-то вроде

Код: plaintext
select row_count() over(), moment,...,online, not online and lag(online,1,true) over () as thestart, online and not lag(online,1,true) over () as theend ... order by moment...

Из того, что получилось убрать where not thestart and not theend и склеить по row_count со сдвигом вверх
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите с группировкой по времени / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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