Как использование круглых скобок при использовании ключевого слова DISTINCT в SQL может вызвать путаницу
Одно из самых распространенных неверных толкований, которое допускают многие пользователи SQL, даже самые опытные, связано с тем, как DISTINCT
применяется к указанным столбцам. Довольно часто можно увидеть запросы SQL, пытающиеся применить предложение SELECT DISTINCT
к подмножеству столбцов, которые должны быть возвращены запросом.
И заблуждение заключается в представлении, что DISTINCT
— это функция, которая по существу принимает имя столбца, к которому она будет применяться, в то время как столбцы, указанные вне «вызова функции», не будут учитываться при вычислении результатов.
Но на самом деле, когда вы пытаетесь использовать круглые скобки, чтобы попытаться сделать DISTINCT
эффективным только для столбцов, заключенных в круглые скобки, это не сработает так, как вы ожидаете.
Теперь давайте создадим пример таблицы, на которую мы будем ссылаться в этой статье, чтобы продемонстрировать несколько концепций и помочь нам прояснить, как именно ключевое слово DISTINCT
работает в SQL.
А теперь добавим несколько записей во вновь созданную таблицу address
.
Теперь давайте запросим результаты, чтобы увидеть окончательный пример таблицы:
Заблуждение о DISTINCT в SQL
Теперь предположим, что мы хотим получить отдельные строки из нашей таблицы rental
, используя два разных поля, а именно customer_id
и store_id
. Другими словами, мы хотели бы ответить на следующий вопрос:
Каковы уникальные комбинации
customer_id
иstore_id
в нашей таблице аренды?
Чтобы ответить на приведенный выше запрос, мы можем просто запросить нашу таблицу и получить значения DISTINCT
для столбцов customer_id
и store_id
:
Теперь, если бы мы хотели получить только уникальный набор клиентов, чтобы в приведенном выше результате запроса мы могли видеть только одну строку для каждого клиента, тогда нам нужно было бы уточнить наш запрос, чтобы сделать это.
И именно в этом заключается неправильное представление о DISTINCT
. У многих пользователей создается (ошибочное!) впечатление, что DISTINCT
— это функция, в которой мы можем указать столбцы, которые мы хотим учитывать при ее применении к нашей целевой таблице.
Если вы попытаетесь заключить customer_id
в круглые скобки при «вызове» (неподходящий глагол здесь, поскольку это не функция) DISTINCT
, вы заметите, что это не имеет никакого эффекта:
Мы по-прежнему можем видеть «дублирующиеся» идентификаторы клиентов в результатах нашего запроса. Это связано с тем, что предложение SELECT DISTINCT
всегда будет учитывать все указанные имена столбцов, независимо от того, были ли они заключены в круглые скобки.
На самом деле все приведенные ниже выражения действительно эквивалентны:
SELECT DISTINCT customer_id, store_id FROM rental;
SELECT DISTINCT (customer_id), store_id FROM rental;
SELECT DISTINCT (customer_id), (store_id) FROM rental;
SELECT DISTINCT (store_id), customer_id FROM rental;
SELECT DISTINCT ((customer_id)), store_id FROM rental;
В заключение, я бы настоятельно рекомендовал избегать использования круглых скобок при использовании предложения SELECT
с квалификатором DISTINCT
, так как это может привести к тому, что другие люди (которые могут не знать о том, что мы сегодня обсуждали) неправильно истолковать запрос и случайно подумать, что вы намерены применить DISTINCT
к одному столбцу, несмотря на то, что это невозможно, как мы уже продемонстрировали.
PostgreSQL и DISTINCT ON
Если вы работаете с Postgres и хотели бы применить DISTINCT
только к подмножеству столбцов, которые вы хотите получить в своих результатах, вы можете воспользоваться преимуществом DISTINCT ON
.
SELECT DISTINCT
удаляет повторяющиеся строки из результата.
SELECT DISTINCT ON
удаляет строки, соответствующие всем указанным выражениям.
— Постгрес Документация
Это расширение построено на основе DISTINCT
стандартного SQL и возвращает первую строку для каждого набора строк, соответствующих указанному выражению.
Однако обратите внимание, что при использовании DISTINCT ON
имеет смысл также использовать предложение ORDER BY
. Таким образом, вы сможете указать условия выбора желаемого результата из конфликтующих строк. Например, если две строки соответствуют вашему выражению (в приведенном выше примере у нас есть две записи, соответствующие клиенту с идентификатором 100
).
Теперь давайте предположим, что мы хотим получить уникальные идентификаторы клиентов с соответствующим идентификатором магазина, но на этот раз, если существует несколько конкурирующих строк, мы хотели бы получить строку с наименьшей суммой:
Обратите внимание, что store_id
, соответствующее customer_id=100
, изменилось, поскольку строка аренды с наименьшей суммой отличается теперь, когда мы упорядочили наши результаты по сумме в порядке возрастания.
Но в целом, если вас не особо волнует порядок, то его можно опустить.
Последние мысли
Важно понимать, как ключевое слово DISTINCT
работает с операторами SELECT
в SQL, так как это является источником путаницы для многих пользователей, и я бы сказал, даже для опытных.
При написании запросов с предложениями SELECT DISTINCT
многие пользователи склонны использовать DISTINCT
так же, как и с правильными функциями SQL. Другими словами, они заключают один столбец в круглые скобки, в то же время они предоставляют больше имен столбцов после предложения — например, SELECT DISTINCT(user_id), first_name FROM ...
.
При чтении таких запросов (и, очевидно, людей, их пишущих) вы можете прийти к выводу, что SELECT DISTINCT
применимо только к указанному столбцу (например, user_id
), а не к остальным столбцам (например, first_name
). И, как мы видели в сегодняшней статье, это заблуждение и довольно опасное предположение при написании запросов.
Наконец, мы обсудили особый случай в базе данных PostgreSQL, который позволяет пользователям явно указать, какой столбец следует учитывать при применении DISTINCT
, используя специальное предложение DISTINCT ON
.
Стать участником и читать все истории на Medium. Ваш членский взнос напрямую поддерживает меня и других писателей, которых вы читаете. Вы также получите полный доступ ко всем историям на Medium.
Статьи по теме, которые вам также могут понравиться
Таблицы фактов и измерений
Понимание разницы между таблицами фактов и измерений в контексте схемы «звезда и хранилища данныхtowardsdatascience.com»