Как найти строки между двумя датами в строке - PullRequest
1 голос
/ 25 апреля 2020

У меня есть следующая таблица:

topic_id conversation      logical_date         start_date        end_date        type
1            1           2020-01-01 09:00    2020-01-01 09:00  2020-01-01 09:50 phone call
1            2           2020-01-01 09:14                                         text
1            3           2020-01-01 10:27                                         text
2            1           2020-02-03 08:40                                         text

В этой таблице представлены запросы поддержки. Каждый запрос поддержки имеет topi c, а topi c имеет 1 или более разговоров.

Я хочу найти все текстовые запросы, которые выполнялись между start_date и end_date телефонного звонка.

Поэтому для приведенной выше таблицы я хочу видеть:

topic_id conversation_id start_date            end_date        sum
 1            1           2020-01-01 09:00 2020-01-01 09:50     1 

Лог c: Для каждого topic_id введите = 'phone call', возьмите start_date и end_date, сравните их с беседами type = 'text' из this topic_id суммирует тех, кто их логическая_дата между start_date и end_date

Я знаю, что мне нужно сделать это с помощью оконной функции, но я не уверен, как.

Это то, что я имею до сих пор:

select topic_id, conversation_id, start_date, end_date, count(1 ) over partition by () 
from table
where type = 'phone call'

Я использую Presto

Ответы [ 2 ]

1 голос
/ 25 апреля 2020

Вы можете использовать коррелированный подзапрос, чтобы подсчитать, сколько 'text' записей может быть найдено для одного и того же topic_id для каждой 'phone call' записи:

select
    t.*,
    (
        select count(*)
        from mytable t1
        where 
            t1.topic_id = t.topic_id
            and t1.type = 'text'
            and t1.logical_date >= t.start_date
            and t1.logical_date <  t.end_date
    ) cnt
from mytable t
where t.type = 'phone call'

Для производительности требуется индекс на (topic_id, type, logical_date).

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

1 голос
/ 25 апреля 2020

Я думаю, что вы хотите:

select t.*
from t
where t.type = 'text' and
      exists (select 1
              from t t2
              where t2.conversation_id = t.conversation_id and
                    t.logical_date between t2.start_date and t2.end_date and
                    t2.type = 'phone'
             );

Если вы действительно хотите получить информацию из обеих записей, используйте join:

select tt.*, tp.*
from t tt join
     t tp
     on tp.conversation_id = tt.conversation_id and
        tt.logical_date between tp.start_date and tp.end_date and
        tp.type = 'text' and
        tp.type = 'phone';
...