Я узнал кое-что простое о SQL на днях:
SELECT c FROM myTbl GROUP BY C
Имеет тот же результат, что и:
SELECT DISTINCT C FROM myTbl
Что мне интересно, есть ли что-то другое в том, как механизм SQL обрабатывает команду, или это действительно одно и то же?
Я лично предпочитаю четкий синтаксис, но я уверен, что это больше по привычке, чем что-либо еще.
РЕДАКТИРОВАТЬ: Это не вопрос о агрегатах. Использование GROUP BY
с агрегатными функциями понятно.
SELECT c FROM myTbl UNION SELECT c FROM myTbl
и получить тот же результат ... Но зачем все усложнять, когда SELECT DISTINCT так просто.GROUP BY
намного раньше, чем «SELECT» иDISTINCT
следует за «select».DISTINCT
результате фактически выбирается поле, т. Е. Значение будет отображаться в наборе результатов.GROUP BY
может эффективно удалять дубликаты без фактического выбора поля. В большинстве случаев это несколько неактуально, но может быть именно тем, что вы хотите в других. Если вы в конечном итоге используетеGROUP BY
вместоDISTINCT
, пояснительный комментарий в коде, вероятно, оправдан.Ответы:
Ответ MusiGenesis является функционально правильным в отношении вашего вопроса, как указано; SQL Server достаточно умен, чтобы понять, что если вы используете «Группировать по» и не используете никаких агрегатных функций, то на самом деле вы имеете в виду «Отличительный» - и, следовательно, он генерирует план выполнения, как если бы вы просто использовали «Отличительный» «.
Тем не менее, я думаю, что важно отметить реакцию Хэнка , а также - кавалерийское обращение с «Group By» и «Distinct» может привести к пагубным ошибкам в будущем, если вы не будете осторожны. Не совсем правильно говорить, что это «не вопрос об агрегатах», потому что вы спрашиваете о функциональной разнице между двумя ключевыми словами SQL-запроса, одно из которых предназначено для использования с агрегатами, а другое - нет.
Иногда молоток может вбить винт, но если у вас под рукой есть отвертка, зачем?
(для целей этой аналогии
Hammer : Screwdriver :: GroupBy : Distinct
иscrew => get list of unique values in a table column
)источник
GROUP BY
позволяет использовать агрегатные функции, какAVG
,MAX
,MIN
,SUM
иCOUNT
. С другой стороныDISTINCT
просто удаляет дубликаты.Например, если у вас есть куча записей о покупках, и вы хотите знать, сколько было потрачено каждым отделом, вы можете сделать что-то вроде:
Это даст вам одну строку для каждого отдела, содержащую название отдела и сумму всех
amount
значений во всех строках для этого отдела.источник
DISTINCT
+ агрегатные функции? вот так:select distinct department, SUM(amount) from ...
Разницы нет (в SQL Server, по крайней мере). Оба запроса используют один и тот же план выполнения.
http://sqlmag.com/database-performance-tuning/distinct-vs-group
Может быть , есть разница, если есть суб-запросы участия:
http://blog.sqlauthority.com/2007/03/29/sql-server-difference-between-distinct-and-group-by-distinct-vs-group-by/
Нет никакой разницы (в стиле Oracle):
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:32961403234212
источник
В чем отличие с точки зрения простого удаления дубликатов
Помимо того факта, что, в отличие от этого
DISTINCT
,GROUP BY
допускается агрегирование данных по группам (что было упомянуто во многих других ответах), самым важным отличием, на мой взгляд, является тот факт, что две операции «происходят» на двух очень разных этапах в логическом порядке. операций, которые выполняются вSELECT
заявлении .Вот самые важные операции:
FROM
( в том числеJOIN
,APPLY
и т.д.)WHERE
GROUP BY
(можно удалить дубликаты)HAVING
SELECT
DISTINCT
(можно удалить дубликаты)UNION
,INTERSECT
,EXCEPT
(Можно удалить дубликаты)ORDER BY
OFFSET
LIMIT
Как видите, логический порядок каждой операции влияет на то, что можно сделать с ней, и как она влияет на последующие операции. В частности, тот факт , что
GROUP BY
операция «происходит до» наSELECT
операции (проекция) означает , что:1. Это не зависит от проекции
Пример, в котором полезно не зависеть от проекции, - это если вы хотите рассчитать оконные функции по различным значениям:
При запуске с базой данных Sakila это дает:
Этого не может быть достигнуто с
DISTINCT
легкостью:Этот запрос «неправильный» и дает что-то вроде:
Это не то, что мы хотели.
DISTINCT
Операция «не происходит после того, как » проекция, поэтому мы больше не можем удалитьDISTINCT
рейтинги , потому что функция окна уже рассчитаны и прогнозируемые. Чтобы использоватьDISTINCT
, нам нужно было бы вложить эту часть запроса:Примечание: в данном конкретном случае мы могли бы также использовать
DENSE_RANK()
2. Он не может использовать какие-либо значения из проекции
Одним из недостатков SQL является его многословие. По той же причине, что мы видели раньше (а именно, логический порядок операций), мы не можем «легко» группировать то, что мы проецируем.
Это неверный SQL:
Это верно (повторяет выражение)
Это также верно (вложенное выражение)
Я написал об этой теме более подробно в блоге
источник
WHERE
но возможноGROUP BY
). В любом случае, я думаю, что это плохая идея, и я предлагаю никогда не использовать эту функцию в целях переносимости и обслуживания. «Внезапно» это больше не будет работать, например, при наложении псевдонимов на агрегатную функцию или оконную функцию.never using that feature for portability and maintenance reasons
!! согласился на 100% ... и теперь я тоже получаю удовольствие от вашего блога, отличная работа. Приветствия.Используйте,
DISTINCT
если вы просто хотите удалить дубликаты. Используйте ,GROUPY BY
если вы хотите применить агрегатные операторы (MAX
,SUM
,GROUP_CONCAT
..., илиHAVING
оговорка).источник
Я ожидаю, что есть вероятность тонких различий в их исполнении. Я проверил планы выполнения для двух функционально эквивалентных запросов по этим направлениям в Oracle 10g:
Средняя операция немного отличается: «HASH GROUP BY» и «HASH UNIQUE», но предполагаемые затраты и т. Д. Идентичны. Затем я выполнил их с включенной трассировкой, и фактическое количество операций было одинаковым для обоих (за исключением того, что второй не должен был выполнять какие-либо физические чтения из-за кэширования).
Но я думаю, что из-за того, что имена операций отличаются, выполнение будет следовать несколько иным путям кода, и это открывает возможность более существенных различий.
Я думаю, что вы должны предпочесть синтаксис DISTINCT для этой цели. Это не просто привычка, это более четко указывает на цель запроса.
источник
Для отправленного вами запроса они идентичны. Но для других запросов это может быть не так.
Например, это не то же самое, что:
источник
Я прочитал все приведенные выше комментарии, но не увидел, чтобы кто-то указывал на основное различие между Group By и Distinct, кроме бита агрегации.
Distinct возвращает все строки, а затем дедуплицирует их, тогда как Group By дедуплицирует строки, когда они читаются алгоритмом одна за другой.
Это означает, что они могут давать разные результаты!
Например, приведенные ниже коды дают разные результаты:
Если в таблице 10 имен, из которых 1 является дубликатом другого, то первый запрос возвращает 10 строк, тогда как второй запрос возвращает 9 строк.
Причина в том, что я сказал выше, чтобы они могли вести себя по-другому!
источник
Name
втором запросе вы группируете только одно, аdistinct
ключевое слово применяется как к столбцам, такName
и к вашемуROW_NUMBER()
столбцу вselect
предложении первого запроса. Если бы вы также сгруппировали по первому столбцу во втором запросе, запросы вернули бы те же результаты.order of execution
из пунктов SQL , который представляет собой (в общем смысле)FROM and ON (joins)
,WHERE
,GROUP BY
,HAVING
,SELECT
,DISTINCT
,ORDER BY
,LIMIT / OFFSET / TOP
поэтому второй запрос имена уменьшаются в количестве по группе и позже row_number () применяется в результате в одном ряду за уникальное имя. В первом запросе row_number () применяется до того, как применяется отличное, и из-за природы функции row_number () каждая строка получает уникальное целое число, таким образом, каждая строка возвращается, даже если есть повторяющиеся значения имени.Если вы используете DISTINCT с несколькими столбцами, результирующий набор не будет сгруппирован, как это будет с GROUP BY, и вы не сможете использовать агрегатные функции с DISTINCT.
источник
Они имеют различную семантику, даже если у них есть эквивалентные результаты для ваших конкретных данных.
источник
GROUP BY имеет очень специфическое значение, отличное (хе) от функции DISTINCT.
GROUP BY приводит к тому, что результаты запроса группируются с использованием выбранного выражения, затем могут применяться агрегатные функции, которые будут действовать на каждую группу, а не на весь набор результатов.
Вот пример, который может помочь:
Учитывая таблицу, которая выглядит так:
Этот запрос:
Будет производить вывод, как это:
Что, очевидно, сильно отличается от использования DISTINCT. Если вы хотите сгруппировать свои результаты, используйте GROUP BY, если вы просто хотите получить уникальный список определенного столбца, используйте DISTINCT. Это даст вашей базе данных возможность оптимизировать запрос для ваших нужд.
источник
Пожалуйста, не используйте GROUP BY, когда вы имеете в виду DISTINCT, даже если они работают одинаково. Я предполагаю, что вы пытаетесь сэкономить миллисекунды от запросов, и я должен отметить, что время разработки на порядок дороже, чем время компьютера.
источник
Если вы используете GROUP BY без какой-либо агрегатной функции, то внутренне она будет обрабатываться как DISTINCT, поэтому в этом случае нет разницы между GROUP BY и DISTINCT.
Но когда вам предоставляется предложение DISTINCT, лучше использовать его для поиска ваших уникальных записей, поскольку целью GROUP BY является достижение агрегации.
источник
group by используется в агрегатных операциях - например, когда вы хотите получить количество Bs с разбивкой по столбцу C
это звучит по-разному - вы получаете уникальные строки.
В SQL Server 2005 похоже, что оптимизатор запросов может оптимизировать разницу в упрощенных примерах, которые я запускал. Не знаю, если вы можете рассчитывать на это во всех ситуациях, хотя.
источник
В этом конкретном запросе нет никакой разницы. Но, конечно, если вы добавите какие-либо статистические столбцы, вам придется использовать группирование по.
источник
В перспективе 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.
источник
Teradata
?С точки зрения «языка SQL» эти две конструкции эквивалентны, и то, что вы выбираете, является одним из тех вариантов «образа жизни», которые мы все должны сделать. Я думаю, что есть хороший пример того, что DISTINCT является более явным (и, следовательно, более внимательным к человеку, который унаследует ваш код и т. Д.), Но это не означает, что конструкция GROUP BY является недопустимым выбором.
Я думаю, что «GROUP BY для агрегатов» - неправильный акцент. Люди должны знать, что функция set (MAX, MIN, COUNT и т. Д.) Может быть опущена, чтобы они могли понять намерения кодера, когда оно есть.
Идеальный оптимизатор распознает эквивалентные конструкции SQL и всегда соответственно выберет идеальный план. Для выбора реального движка SQL вы должны протестировать :)
PS обратите внимание, что положение ключевого слова DISTINCT в предложении select может давать разные результаты, например, контраст:
источник
Вы замечаете это только потому, что выбираете один столбец.
Попробуйте выбрать два поля и посмотрите, что произойдет.
Group By предназначена для использования следующим образом:
Который будет показывать сумму всех транзакций для каждого человека.
источник
Я знаю, что это старый пост. Но бывает, что у меня был запрос, который использовал group by, чтобы просто возвращать различные значения при использовании этого запроса в отчетах toad и oracle, все работало нормально, я имею в виду хорошее время отклика. Когда мы перешли с Oracle 9i на 11g, время отклика в Toad было превосходным, но в отчете на завершение отчета ушло около 35 минут, а при использовании предыдущей версии - около 5 минут.
Решением было изменить группу и использовать DISTINCT, и теперь отчет выполняется примерно за 30 секунд.
Я надеюсь, что это полезно для кого-то с такой же ситуацией.
источник
С точки зрения использования, GROUP BY используется для группировки строк, которые вы хотите вычислить. DISTINCT не будет делать никаких расчетов. Это не покажет повторяющихся строк.
Я всегда использовал DISTINCT, если я хочу представить данные без дубликатов.
Если я хочу сделать расчеты, такие как суммирование общего количества манго, я буду использовать GROUP BY
источник
Я всегда понимал, что использование различных - это то же самое, что группирование по каждому полю, выбранному вами в порядке их выбора.
то есть:
такой же как:
источник
Функциональная эффективность совершенно иная. Если вы хотите выбрать только «возвращаемое значение», за исключением дубликата, лучше использовать отличный, чем группировать по. Поскольку «группировать по» включают (сортировка + удаление), «отличные» включают (удаление)
источник
В Hive (HQL) группирование по может выполняться намного быстрее, чем по-разному, поскольку первое не требует сравнения всех полей в таблице. См. Https://sqlperformance.com/2017/01/t-sql-queries/surprises-assumptions-group-by-distinct .
источник
Иногда они могут дать вам одинаковые результаты, но они предназначены для использования в другом смысле / случае. Основное отличие заключается в синтаксисе.
Обратите внимание на пример ниже.
DISTINCT
используется для фильтрации дублированного набора значений. (6, cs, 9.1) и (1, cs, 5.5) - два разных набора. ТакDISTINCT
что будет отображать обе строки, в то времяGROUP BY Branch
как будет отображать только один набор.Иногда результаты, которые могут быть достигнуты с помощью
GROUP BY
предложения, не могут быть достигнутыDISTINCT
без использования какого-либо дополнительного условия или условия. Например, в вышеуказанном случае.Чтобы получить такой же результат, как
DISTINCT
вы должны передать все имена столбцов вGROUP BY
предложении, как показано ниже. Итак, посмотрите на синтаксическую разницу. Вы должны знать все имена столбцов, чтобы использоватьGROUP BY
предложение в этом случае.Также я заметил,
GROUP BY
отображает результаты в порядке возрастания по умолчанию, которыйDISTINCT
не делает. Но я не уверен в этом. Это может отличаться от поставщика.Источник: https://dbjpanda.me/dbms/languages/sql/sql-syntax-with-examples#group-by
источник
Как правило, мы можем использовать
DISTINCT
для устранения дубликатов по конкретному столбцу в таблице.Пример :
источник
Нет значительного различия между выражением group by и выражением отдельно, за исключением использования агрегатных функций. И то, и другое можно использовать для различения значений, но если с точки зрения производительности, группировать лучше. Когда используется отдельное ключевое слово, внутренне используется операция сортировки, которую можно просмотреть в плане выполнения.
Попробуйте простой пример
Объявить таблицу @tmpresult (Id tinyint)
Вставить в @tmpresult Выбрать 5 Объединить все Выбрать 2 Объединить все Выбрать 3 Объединить все Выбрать 4
Выберите отличный идентификатор из @tmpresult
источник