Есть ли разница между GROUP BY и DISTINCT? - PullRequest
272 голосов
/ 03 октября 2008

Я узнал кое-что простое о SQL на днях:

SELECT c FROM myTbl GROUP BY C

Имеет тот же результат, что и:

SELECT DISTINCT C FROM myTbl

Что мне интересно, есть ли что-то другое в том, как механизм SQL обрабатывает команду, или это действительно одно и то же?

Лично я предпочитаю четкий синтаксис, но я уверен, что это скорее привычка, чем все остальное.

РЕДАКТИРОВАТЬ: Это не вопрос о агрегатах. Использование GROUP BY с агрегатными функциями понятно.

Ответы [ 23 ]

5 голосов
/ 28 декабря 2011

Если вы используете GROUP BY без какой-либо агрегатной функции, то внутренне она будет рассматриваться как DISTINCT, поэтому в этом случае нет разницы между GROUP BY и DISTINCT.

Но когда вам предоставляется предложение DISTINCT, лучше использовать его для поиска ваших уникальных записей, поскольку целью GROUP BY является достижение агрегации.

5 голосов
/ 03 октября 2008

Пожалуйста, не используйте GROUP BY, когда вы имеете в виду DISTINCT, даже если они работают одинаково. Я предполагаю, что вы пытаетесь сэкономить миллисекунды от запросов, и я должен отметить, что время разработчика на порядок дороже, чем время компьютера.

5 голосов
/ 03 октября 2008

GROUP BY имеет очень специфическое значение, отличное (хе) от функции DISTINCT.

GROUP BY приводит к тому, что результаты запроса группируются с использованием выбранного выражения, затем могут применяться агрегатные функции, которые будут действовать на каждую группу, а не на весь набор результатов.

Вот пример, который может помочь:

Учитывая таблицу, которая выглядит следующим образом:

name
------
barry
dave
bill
dave
dave
barry
john

Этот запрос:

SELECT name, count(*) AS count FROM table GROUP BY name;

Будет выводить как это:

name    count
-------------
barry   2
dave    3
bill    1
john    1

Что, очевидно, сильно отличается от использования DISTINCT. Если вы хотите сгруппировать свои результаты, используйте GROUP BY, если вы просто хотите уникальный список определенного столбца, используйте DISTINCT. Это даст вашей базе данных возможность оптимизировать запрос для ваших нужд.

4 голосов
/ 03 октября 2008

group by используется в агрегатных операциях - например, когда вы хотите получить количество Bs в разбивке по столбцу C

select C, count(B) from myTbl group by C

отличается то, на что это похоже - вы получаете уникальные строки.

В sql server 2005 похоже, что оптимизатор запросов способен оптимизировать разницу в упрощенных примерах, которые я запускал. Не знаю, если вы можете рассчитывать на это во всех ситуациях, хотя.

3 голосов
/ 03 октября 2008

В этом конкретном запросе нет разницы. Но, конечно, если вы добавите какие-либо статистические столбцы, вам придется использовать group by.

2 голосов
/ 19 июня 2018

В перспективе Teradata :

С точки зрения набора результатов не имеет значения, используете ли вы DISTINCT или GROUP BY в Teradata. Набор ответов будет таким же.

С точки зрения производительности, это не то же самое.

Чтобы понять, что влияет на производительность, вам нужно знать, что происходит с Teradata при выполнении оператора с помощью DISTINCT или GROUP BY.

В случае DISTINCT строки перераспределяются немедленно, без какой-либо предварительной агрегации, в то время как в случае GROUP BY на первом шаге выполняется предварительная агрегация, и только после этого уникальные значения перераспределяются по AMP.

Не думайте, что GROUP BY всегда лучше с точки зрения производительности. Когда у вас много разных значений, шаг предварительной агрегации GROUP BY не очень эффективен. Teradata должна отсортировать данные, чтобы удалить дубликаты. В этом случае может быть лучше сначала перераспределить, то есть использовать инструкцию DISTINCT. Только если имеется много повторяющихся значений, оператор GROUP BY, вероятно, является лучшим выбором, поскольку только после выполнения шага дедупликации после перераспределения.

Короче говоря, DISTINCT против GROUP BY в Teradata означает:

GROUP BY -> для многих дубликатов DISTINCT -> нет или только несколько дубликатов. Иногда при использовании DISTINCT вам не хватает места в буфере на AMP. Причина в том, что перераспределение происходит немедленно, и перекос может привести к тому, что AMP не хватит места.

Если это произойдет, у вас, вероятно, больше шансов на использование GROUP BY, поскольку дубликаты уже удалены на первом шаге и меньше данных перемещается по AMP.

2 голосов
/ 03 октября 2008

С точки зрения «языка SQL» эти две конструкции эквивалентны, и какую из них вы выберете, это один из тех вариантов «образа жизни», которые мы все должны сделать. Я думаю, что есть хороший пример того, что DISTINCT является более явным (и, следовательно, более внимательным к человеку, который унаследует ваш код и т. Д.), Но это не означает, что конструкция GROUP BY является недопустимым выбором.

Я думаю, что это «GROUP BY для агрегатов» - неправильный акцент. Люди должны знать, что функция set (MAX, MIN, COUNT и т. Д.) Может быть опущена, чтобы они могли понять намерения кодера, когда оно есть.

Идеальный оптимизатор распознает эквивалентные конструкции SQL и всегда соответственно выбирает идеальный план. Для выбора реального движка SQL вы должны проверить:)

PS обратите внимание, что позиция ключевого слова DISTINCT в предложении select может давать разные результаты, например, контрастность:

SELECT COUNT(DISTINCT C) FROM myTbl;

SELECT DISTINCT COUNT(C) FROM myTbl;
1 голос
/ 29 января 2016

Я знаю, что это старый пост. Но бывает, что у меня был запрос, который использовал group by, чтобы просто возвращать различные значения при использовании этого запроса в отчетах toad и oracle, все работало нормально, я имею в виду хорошее время отклика. Когда мы перешли с Oracle 9i на 11g, время отклика в Toad было превосходным, но в отчете на завершение отчета ушло около 35 минут, а при использовании предыдущей версии - около 5 минут.

Решением было изменить группу и использовать DISTINCT, и теперь отчет выполняется примерно за 30 секунд.

Я надеюсь, что это полезно для кого-то с такой же ситуацией.

1 голос
/ 03 октября 2008

Вы замечаете это только потому, что выбираете один столбец.

Попробуйте выбрать два поля и посмотрите, что получится.

Group By предназначен для использования следующим образом:

SELECT name, SUM(transaction) FROM myTbl GROUP BY name

Который покажет сумму всех транзакций для каждого человека.

0 голосов
/ 01 июля 2018

В Hive (HQL) группирование по может выполняться намного быстрее, чем по отдельности, поскольку первое не требует сравнения всех полей таблицы. Смотри https://sqlperformance.com/2017/01/t-sql-queries/surprises-assumptions-group-by-distinct.

...