Напиши SQL-запрос для поиска значений с более чем одной записью в таблице пользователей
Что проверяют
Группировку с фильтром по агрегату и понимание, что вопрос неполон: дубль всегда по какому-то полю, и это поле надо назвать самому. Для java-разработчика разговор обычно уходит дальше, в то, откуда дубли вообще берутся и почему проверка в коде их не предотвращает.
Как отвечать
Уточните колонку, например почту или логин, и пишите:
SELECT email, count(*) AS cnt
FROM users
GROUP BY email
HAVING count(*) > 1
ORDER BY cnt DESC;Если нужны сами строки, а не сводка, удобнее оконная функция, она оставляет все поля исходной таблицы:
SELECT * FROM (
SELECT u.*, count(*) OVER (PARTITION BY u.email) AS cnt
FROM users u
) t WHERE t.cnt > 1;Дальше переведите разговор на причину. Дубли появляются там, где уникальность держится на проверке «есть ли уже такой» перед вставкой: два потока проходят проверку одновременно и оба вставляют. Лечится уникальным индексом в базе и обработкой исключения нарушения целостности, а чистка старых дублей делается через нумерацию строк внутри группы с удалением всех, кроме первой.
Где спотыкаются
Фильтруют агрегат в WHERE. Условие с count возможно только в HAVING, потому что WHERE отрабатывает до группировки. Ошибка ловится базой сразу, но на доске её допускают постоянно.
Предлагают SELECT DISTINCT. Он дубли прячет, а не находит: задача была показать значения с повторами и их количество, а не получить список без повторов.
Уверены, что проверка в сервисе внутри транзакции гарантирует уникальность. При уровне изоляции по умолчанию две параллельные транзакции не видят незакоммиченных вставок друг друга, поэтому обе проверки проходят успешно. Гарантию даёт только ограничение в базе.