Ищем последовательности без дубликатов - SQL - PullRequest
1 голос
/ 27 октября 2019

Первый раз при переполнении стека.

Мне нужно найти последовательности без дубликатов, используя только SQL.

Если мои данные (https://i.stack.imgur.com/ZP6Iw.jpg)

System   | date | hour
---------+------+-------
Word     | 28/8 | 16:00
Word     | 28/8 | 16:01
Excel    | 28/8 | 16:02
Word     | 28/8 | 16:03
Ppt      | 28/8 | 16:04
Ppt      | 28/8 | 16:05

Тогдамои выходные данные будут системами, которые я использовал, но если я использовал систему более одного раза без другой системы «в середине», она будет записана один раз. Это не обычная проблема «удаления дубликатов». Дубликаты появляются только тогда, когда две идентичные системыодин за другим.

(https://i.stack.imgur.com/iG7Cn.jpg)

System  | date  
--------+-------
Word    | 28/8
Excel   | 28/8 
Word    | 28/8 
Ppt     | 28/8 

Я использую presto, где я ограничен такими функциями, как 'while'.

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 28 октября 2019

Это проблема пробелов и островов. Вы хотите сгруппировать последовательные записи, принадлежащие одному и тому же System.

Вы можете решить это с помощью оконных функций (которые доступны в presto):

select min(system) system, min(date) date, count(*) nb_records
from (
    select 
        t.*,
        row_number() over(order by date, hour) rn1,
        row_number() over(partition by system order by date, hour) rn2
    from mytable t
) t
group by rn1 - rn2
order by min(rn1)

Я настоятельно рекомендую объединить столбцы date и time в уникальный столбец всоответствующий тип даты / времени. Разделение этой информации на два столбца усложняет ее использование.

В этой Db Fiddle с примерами данных запрос возвращает:

system | date                | nb_records
:----- | :------------------ | ---------:
Word   | 28/08/2019 00:00:00 |          2
Excel  | 28/08/2019 00:00:00 |          1
Word   | 28/08/2019 00:00:00 |          1
Ppt    | 28/08/2019 00:00:00 |          2
0 голосов
/ 27 октября 2019

Так как у меня нет способа проверить на готовность, я не знаю, сработает ли это на самом деле.
Так что это всего лишь некоторый стандартный SQL, который использует оконную функцию LAG для отфильтровывания того же следующего "System" ната же дата.

SELECT q.System, q.date
FROM
(
    SELECT 
     t.System, 
     t.date,
     t.hour,
     LAG(t.System) OVER (PARTITION BY t.date ORDER BY t.hour ASC) AS prevSystem
    FROM YourTable t
) AS q
WHERE (q.System != q.prevSystem OR q.prevSystem IS NULL)
ORDER BY q.date, q.hour
...