SQL скрипт для определения фродового вызова в одно время из разных городов

Ребята, привет!

Помогите пож-та разобраться, как корректно построить скрипт на SQL

Есть таблица совершенных абонентами звонков:

введите сюда описание изображения

Как корректно найти все вызовы, совершенные в один день но из разных городов. По ключу PK (User,Card,Calling_TIME)

То есть нужно из базы с милионнами записей найти фродовые вызовы, которые проходили в одно время из разных городов. Буду очень признателен за помощь!


Ответы (1 шт):

Автор решения: Сергей

Окончательный ответ с учетом объяснения в комментариях, что "Определением фрода является случай, когда один абонент за один день позвонил из разных городов. [...] Исключить только те звонки, когда абонент звонил только из одного города за один день." И учитывая, что на Oracle у вас код предыдущий работал, я просто добавил сюда слово DISTINCT (преверил с ним на mySQL на чистом DATETIME - звонки из одного города предсказуемо убираются).

За конкретный день будет ключ все же не с "Calling_TIME", а с (условно) "Calling_DATE".

Код:

SELECT id, User, card, DATE(calling_Time) AS Calling_DATE, City 
FROM calls
WHERE (User, card, DATE(calling_Time)) IN ((
    SELECT User, card, DATE(calling_Time)  
    FROM calls
    GROUP BY User, card, DATE(calling_Time)
    HAVING COUNT(DISTINCT City) > 1));

Код с проверкой:

CREATE TABLE calls(
    id INT PRIMARY KEY AUTO_INCREMENT,
    user VARCHAR (25),
    card INT,
    calling_Time DATETIME,
    City VARCHAR (25)
);
INSERT INTO calls (user, card, calling_Time, City)
    VALUES
    (1, 1, '2018-05-25 21:25:54', 'Москва'),
    (2, 1, '2018-05-25 21:25:54', 'Самара'),
    (2, 1, '2018-05-25 21:25:54', 'Самара'),
    (1, 1, '2018-05-26 21:25:54', 'Москва'),
    (1, 1, '2018-05-25 21:25:54', 'Питер')
;
SELECT * FROM calls;

SELECT id, User, card, DATE(calling_Time) AS Calling_DATE, City 
FROM calls
WHERE (User, card, DATE(calling_Time)) IN ((
    SELECT User, card, DATE(calling_Time)  
    FROM calls
    GROUP BY User, card, DATE(calling_Time)
    HAVING COUNT(DISTINCT City) > 1));

Вывод:

Affected rows: 0

Affected rows: 5

Query result:
+----+------+------+---------------------+--------+
| id | user | card | calling_Time        | City   |
+----+------+------+---------------------+--------+
| 1  | 1    | 1    | 2018-05-25 21:25:54 | Москва |
| 2  | 2    | 1    | 2018-05-25 21:25:54 | Самара |
| 3  | 2    | 1    | 2018-05-25 21:25:54 | Самара |
| 4  | 1    | 1    | 2018-05-26 21:25:54 | Москва |
| 5  | 1    | 1    | 2018-05-25 21:25:54 | Питер  |
+----+------+------+---------------------+--------+
Affected rows: 5

Query result:
+----+------+------+---------------------+--------+
| id | User | card | calling_Date        | City   |
+----+------+------+---------------------+--------+
| 1  | 1    | 1    | 2018-05-25          | Москва |
| 5  | 1    | 1    | 2018-05-25          | Питер  |
+----+------+------+---------------------+--------+
Affected rows: 2
→ Ссылка