Короткий ответ
Нужно сгруппировать таблицу по этим двум столбцам, посчитать количество строк в каждой группе через COUNT(*) и отобрать группы с HAVING COUNT(*) > 1 — это и есть дубликаты.
Как это работает подробнее
GROUP BY email, order_date объединяет все строки с одинаковой комбинацией этих значений в одну группу; COUNT(*) в каждой группе показывает, сколько исходных строк туда попало, а HAVING отфильтровывает только те группы, где это число больше 1.
Пример кода
Запрос SQL
SELECT email, order_date, COUNT(*) AS cnt
FROM orders
GROUP BY email, order_date
HAVING COUNT(*) > 1
ORDER BY cnt DESC;Что использовать на практике
- На практике: перед любой агрегацией метрик (суммы, средние) полезно сначала явно проверить данные на дубликаты именно таким запросом — это быстрый и наглядный способ понять масштаб проблемы до того, как строить отчёт. Дубликаты могут появляться из-за повторной выгрузки данных, сбоя в ETL или неправильного JOIN на предыдущем шаге.
- Результат: Если результат пустой — дубликатов по этой комбинации нет.
- Проверка: для одной найденной пары email+дата вручную просмотреть все строки через
SELECT * FROM orders WHERE email = ... AND order_date = ...и понять, действительно ли это задвоение.
Подводные камни
- Частая ошибка: находят дубликаты, но сразу удаляют их все без анализа причины — иногда «дубликаты» на самом деле разные события с одинаковыми значениями полей (например, два разных товара, купленных в одну секунду), и бездумное удаление искажает данные.