Mysql: получить количество записей - PullRequest
1 голос
/ 05 мая 2020

Есть 2 таблицы MariaDB (Ver 15.1 Distrib 5.5.64-MariaDB, для Linux (x86_64)):

CREATE TABLE Table1
    (`phone` int, `calldate` datetime)
;

INSERT INTO Table1
    (`phone`, `calldate`)
VALUES
    (123, '2020-01-01 10:00:00'),
    (123, '2020-01-01 11:00:00'),
    (123, '2020-01-01 12:00:00')
;

CREATE TABLE Table2
    (`phone` int, `calldate` datetime)
;

INSERT INTO Table2
    (`phone`, `calldate`)
VALUES
( 123, '2020-01-01 09:01:00'),
( 123, '2020-01-01 09:02:00'),
( 123, '2020-01-01 10:15:00'),
( 123, '2020-01-01 10:20:00'),
( 123, '2020-01-01 10:23:00'),
( 123, '2020-01-01 11:05:00'),
( 123, '2020-01-01 11:12:00'),
( 123, '2020-01-01 11:25:00')
;

Как получить результат как: Calldate первой записи из table1 ( 2020-01-01 10:00:00) позже, чем дата вызова двух записей из таблицы2. Аналогично для второго - счет 5 (с 09:01:00 до 10:23:00), но две записи из table2 с calldate 09:01:00 и 09:02:00 уже «перекрываются» первой записью из table1, поэтому результат должен быть 3 вместо 5.

|------+----------------------+-------+
| phone | calldate            | count |
|-------+---------------------+-------+
| 123   | 2020-01-01 09:02:00 | 2     |
| 123   | 2020-01-01 10:23:00 | 3     |
| 123   | 2020-01-01 11:25:00 | 3     |
|------+---------------------+|------+|

Кроме того, calldate в наборе результатов должен быть самым последним calldate из "перекрывающегося" подмножества.

Ответы [ 2 ]

1 голос
/ 05 мая 2020

Вы можете сделать это с помощью оконных функций:

select t1.phone, t1.calldate, count(t2.phone)
from (select t1.*,
             lead(calldate) over (partition by phone order by calldate) as next_calldate
      from table1 t1
     ) t1 left join
     table2 t2
     on t2.phone = t1.phone and
        t2.calldate >= t1.calldate and
        (t2.calldate < t1.next_calldate or t1.next_calldate is null)
group by t1.phone, t1.calldate;

EDIT:

Вы можете следовать той же идее с коррелированным подзапросом:

select t1.phone, t1.calldate, count(t2.phone)
from (select t1.*,
             (select min(tt1.calldate)
              from table1 tt1
              where tt1.calldate > t1.calldate
             ) as next_calldate
      from table1 t1
     ) t1 left join
     table2 t2
     on t2.phone = t1.phone and
        t2.calldate >= t1.calldate and
        (t2.calldate < t1.next_calldate or t1.next_calldate is null)
group by t1.phone, t1.calldate;

Это будет быть даже менее эффективным, чем версия оконных функций.

0 голосов
/ 05 мая 2020

Присоединитесь к таблицам и используйте NOT EXISTS в предложении ON, например:

select t1.phone, t1.calldate, count(t2.calldate) count
from Table1 t1 left join Table2 t2
on t2.phone = t1.phone and t2.calldate < t1.calldate
and not exists (
  select 1 from Table1
  where calldate < t1.calldate and t2.calldate < calldate
)  
group by t1.phone, t1.calldate

См. demo . Результатов:

| phone | calldate            | count |
| ----- | ------------------- | ----- |
| 123   | 2020-01-01 10:00:00 | 2     |
| 123   | 2020-01-01 11:00:00 | 3     |
| 123   | 2020-01-01 12:00:00 | 3     |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...