Что делает ключевое слово DISTINCT в SQL
Что проверяют
Понимаете ли вы, что DISTINCT относится ко всей выбранной строке, а не к одному столбцу, и умеете ли отличить настоящие дубликаты от тех, которые породили сами. Тестировщику этот вопрос задают вместе с задачей на проверку данных.
Как отвечать
DISTINCT убирает из результата повторяющиеся строки, причём сравниваются все столбцы в select одновременно.
select distinct city, status from users;Вернутся уникальные пары, а не уникальные города отдельно и статусы отдельно. Это первое, что проверят уточняющим вопросом.
Дальше назовите неочевидное:
- при сравнении строк два NULL считаются одинаковыми и схлопываются, хотя обычное сравнение на равенство с NULL даёт неопределённость;
- уникализация работает после
whereи доorder by, поэтому сортировать можно только по тому, что попало вselect; count(distinct col)считает уникальные значения и пропускает NULL, аcount(*)считает строки;- то же самое часто выражается через
group byбез агрегатов, а когда нужна одна строка на ключ с произвольными полями, берут оконную нумерацию, а неDISTINCT.
Для проверочной задачи скажите, что дубликаты сначала объясняют, а потом убирают: обычно они приходят из соединения один ко многим или из повторной загрузки данных.
Где спотыкаются
Думают, что уникализация применяется к первому столбцу. Отсюда удивление, почему выборка distinct user_id, created_at вернула те же строки: время у записей разное, значит каждая пара уникальна.
Второе: лечат DISTINCT симптом. Если соединение размножило строки, уникализация спрячет проблему, а суммы и счётчики в отчёте всё равно останутся неверными. Дефект формулируется как дублирование данных из-за связи, а не как «не хватает distinct».
Третье: забывают про стоимость. Уникализация требует сортировки или хеширования всего результата, и на большой выборке это заметно. А если уникальность обязано обеспечивать ограничение в базе, то дубликаты это баг данных, и хороший тест их ловит, а не прячет.