Как мне посчитать отдельные события за последовательные секунды? - PullRequest
1 голос
/ 17 октября 2019

У меня есть база данных с несколькими столбцами, датой, отметкой времени (ЧЧ: ММ: СС) и телефонными номерами. Я пытаюсь найти способ найти уникальные звонки в течение нескольких секунд. Например:

Date          Timestamp     Phone_number
10-12-2019    15:15:23      999-999-9999
10-12-2019    15:15:23      999-999-9999
10-12-2019    15:15:24      999-999-9999
10-12-2019    15:15:24      999-999-9999
10-12-2019    15:15:25      999-999-9999
10-12-2019    15:20:21      111-111-1111
10-12-2019    15:20:21      111-111-1111
10-12-2019    15:20:22      111-111-1111
10-12-2019    15:22:33      999-999-9999

В идеале я бы хотел посчитать первые 999-999-9999 как один звонок, а 111-111-1111 как один звонок, а второй звонок 999-999-9999 каквызов на основе вызовов имеет одинаковую метку времени или произошел в последовательных секундах.

С выводом, подобным этому, со счетом 1 с мин (метка времени) непоследовательного вызова:

Date          Timestamp     Phone_number
10-12-2019    15:15:23      999-999-9999
10-12-2019    15:20:21      111-111-1111
10-12-2019    15:22:33      999-999-9999

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

SELECT t1.time, t1.phone_number, COUNT(DISTINCT t2.x)
FROM myTable AS t1
JOIN myTable AS t2 ON t2.timestamp BETWEEN DATE_SUB(t1.timestamp, INTERVAL 1 second) AND t1.timestamp
GROUP BY t1.timestamp, t1.phone_number

Я использую MySql. Открыта для любой помощи! Заранее спасибо

Ответы [ 2 ]

1 голос
/ 17 октября 2019

Это сложная проблема. Это сложно, потому что:

  • У вас есть столбцы даты / времени в двух столбцах.
  • У вас есть повторяющиеся строки.
  • Звонки могут занимать несколько дней.

Итак, я думаю, что лучший подход - это разделение диапазона после объединения столбцов даты и времени в один столбец:

select t.*
from (select t.*,
             max(phone_number) over (partition by phone_number
                                     order by timestamp(date, timestamp)
                                     range between 1 second preceding and current row
                                    ) as prev_phone_number
      from t
     ) t
where prev_phone_number is null or prev_phone_number <> phone_number;
1 голос
/ 17 октября 2019

В MySQL 8.0 это можно решить с помощью оконной функции lag(). Вы можете восстановить дату / время предыдущего вызова на тот же номер в подзапросе, а затем отфильтровать записи, для которых предыдущий вызов на тот же номер произошел за одну секунду до:

select date, timestamp, phone_number
from (
    select 
        t.*,
        lag(concat(date, ' ', timestamp)) 
            over(partition by phone_number order by date, timestamp) lag_datetime
    from mytable t
) x
where 
    lag_datetime is null
    or concat(date, ' ', timestamp) > lag_datetime + interval 1 second

Примечание: сохранениедата и время в разделенных столбцах не очень хорошая идея, поскольку они усложняют логику, когда вам нужно фактически сравнить дату / время.

Демонстрация на DB Fiddle :

| date       | timestamp | phone_number |
| ---------- | --------- | ------------ |
| 2019-10-12 | 15:15:23  | 999-999-9999 |
| 2019-10-12 | 15:20:21  | 111-111-1111 |
| 2019-10-12 | 15:22:33  | 999-999-9999 |
...