DISTINCT vs GROUP BY
26 отговора
875 прегледа
DISTINCT vs GROUP BY
Това два различни начина за групиране ли са или просто DISTINCT не подрежда резултата?
И ако са различни, какви са останалите разлики?
Визирам mySQL.
"Да живееш - значи да се променяш." - Анатол Франс
И ако са различни, какви са останалите разлики?
Визирам mySQL.
"Да живееш - значи да се променяш." - Анатол Франс
Редактирано от Dakota на
Re: DISTINCT vs GROUP BY
Х-м...
--дистинкт не е начин за групиране а просто връща различните стойности.
--Нито дистинкт нито груп бай сортира резултата -- сортирането се управлява от ордер бай, което е съвсем различна клауза.
--за сметка на това и двете (дистинкт и груп бай) използват вътрешна сортировка за да си свършат работата.
-- Някои заявки може да се напишат обаче и по двата начина. Например:
create table t (a int, b int)
insert ..... (да има нещо в таблицата)
select distinct a from t
select a from t group by a
Двата селецта връшат едно и също нещо. Може и да са еднакво бързи (зависи от конкретната субд), но втория ще бъде пълна загадка за човека който ще ти поддържа апликейшъна.
Забележи че
select distinct a, b from t
връща различните двойки (a,b).
Целта на group by е да сметне нещо за групата (т.нар. vector aggregate). Naprimer:
select a, sum(b) from t
или вместо сум: avg|min|max|count (тия aggregate functions се сещам в момента).
Spored SQL standarta в списъка на колоните могат да фигурират само колони изброени в клаузата group by, плюс агрегиращи функции. Някои субд обаче (сайбейс, мс sql server) не налагат това ограничение, което дава възможности за някои хитри приложения.
--дистинкт не е начин за групиране а просто връща различните стойности.
--Нито дистинкт нито груп бай сортира резултата -- сортирането се управлява от ордер бай, което е съвсем различна клауза.
--за сметка на това и двете (дистинкт и груп бай) използват вътрешна сортировка за да си свършат работата.
-- Някои заявки може да се напишат обаче и по двата начина. Например:
create table t (a int, b int)
insert ..... (да има нещо в таблицата)
select distinct a from t
select a from t group by a
Двата селецта връшат едно и също нещо. Може и да са еднакво бързи (зависи от конкретната субд), но втория ще бъде пълна загадка за човека който ще ти поддържа апликейшъна.
Забележи че
select distinct a, b from t
връща различните двойки (a,b).
Целта на group by е да сметне нещо за групата (т.нар. vector aggregate). Naprimer:
select a, sum(b) from t
или вместо сум: avg|min|max|count (тия aggregate functions се сещам в момента).
Spored SQL standarta в списъка на колоните могат да фигурират само колони изброени в клаузата group by, плюс агрегиращи функции. Някои субд обаче (сайбейс, мс sql server) не налагат това ограничение, което дава възможности за някои хитри приложения.
Re: DISTINCT vs GROUP BY
А в някои СУБД (MySQL) в GROUP BY клаузата могат да фигурират колони, които липсват в SELECT частта.
Което дава възможност за още по-хитри приложения ... а също така и за страхотно объркване.
SELECT SUM(a) FROM t GROUP BY b;
salle.online.bg/sig
Което дава възможност за още по-хитри приложения ... а също така и за страхотно объркване.
SELECT SUM(a) FROM t GROUP BY b;
salle.online.bg/sig
не съвсем
GROUP BY сортира резултата. Ето виж:
mysql> select id from test;
+------+
| id |
+------+
| 1 |
| 3 |
| 2 |
| 2 |
| 3 |
+------+
5 rows in set (0.00 sec)
DISTINCT:
mysql> select distinct id from test;
+------+
| id |
+------+
| 1 |
| 3 |
| 2 |
+------+
3 rows in set (0.00 sec)
GROUP BY:
mysql> select id from test group by id;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.00 sec)
Затова ми се струва, че DISTINCT би трябвало да е по-бърз.
"Да живееш - значи да се променяш." - Анатол Франс
mysql> select id from test;
+------+
| id |
+------+
| 1 |
| 3 |
| 2 |
| 2 |
| 3 |
+------+
5 rows in set (0.00 sec)
DISTINCT:
mysql> select distinct id from test;
+------+
| id |
+------+
| 1 |
| 3 |
| 2 |
+------+
3 rows in set (0.00 sec)
GROUP BY:
mysql> select id from test group by id;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.00 sec)
Затова ми се струва, че DISTINCT би трябвало да е по-бърз.
"Да живееш - значи да се променяш." - Анатол Франс
Re: не съвсем
не съм правил тестове, но и аз си мисля, че може би DISTINCT, ще е по-бърз, когато обаче върши работа - когато не върши нужната работа естествено .... не ;-)
но на това, че GROUP BY сортира - изобщо не трябва да разчиташ
но на това, че GROUP BY сортира - изобщо не трябва да разчиташ
Re: не съвсем
Мда...винаги се застраховам и с един ORDER BY, просто това е страничният ефект на GROUP BY, който понякога е доста нежелателен.
"Да живееш - значи да се променяш." - Анатол Франс
"Да живееш - значи да се променяш." - Анатол Франс
неведоми са пътищата..
Ми като го гледам твоя пример и двата резултата са сортирани, което според мен е следствие от това че и двата алгоритъма сортират. Както обаче вече посочиха, не леж на това ухо щото няма гаранция.
Що се отнася до бързината, интуитивно човек си мисли че дистинкта ще е по бърз обаче направих един опит и ето:
в/у таблица от 180,000 реда рънвам
set statistics io on
select distinct sp_name from sp_summary
select sp_name, count(*) from sp_summary group by sp_name
go
Първота заявка ми струва 7457 лог. И/Ота за да прочете таблицата плюс още 188318 лог. И/О-та в/у междинна таблица за сортировка и да извади дистинкта.
За втората заявка пак прави 7457 лог. И/Ота за да прочете таблицата и след това 27000 лог. И/Ота за сортирорка и да сметне каунта.
Излиза че груп бай е около 10 пъти по-бързо!!
Разбира се зависи от субд-то (сайбейс в моя случай), конфигурацията и т.н., но това което искам да кажа е че никога не знаеш докато не го тестваш.
Дистинкт:
grep Table tt.out
Table: sp_summary scan count 1, logical reads: (regular=7457 apf=0
Table: Worktable1 scan count 0, logical reads: (regular=188318 apf=0
Груп бай
Table: sp_summary scan count 1, logical reads: (regular=7457 apf=0
Table: Worktable1 scan count 1, logical reads: (regular=27000 apf=0
Що се отнася до бързината, интуитивно човек си мисли че дистинкта ще е по бърз обаче направих един опит и ето:
в/у таблица от 180,000 реда рънвам
set statistics io on
select distinct sp_name from sp_summary
select sp_name, count(*) from sp_summary group by sp_name
go
Първота заявка ми струва 7457 лог. И/Ота за да прочете таблицата плюс още 188318 лог. И/О-та в/у междинна таблица за сортировка и да извади дистинкта.
За втората заявка пак прави 7457 лог. И/Ота за да прочете таблицата и след това 27000 лог. И/Ота за сортирорка и да сметне каунта.
Излиза че груп бай е около 10 пъти по-бързо!!
Разбира се зависи от субд-то (сайбейс в моя случай), конфигурацията и т.н., но това което искам да кажа е че никога не знаеш докато не го тестваш.
Дистинкт:
grep Table tt.out
Table: sp_summary scan count 1, logical reads: (regular=7457 apf=0
Table: Worktable1 scan count 0, logical reads: (regular=188318 apf=0
Груп бай
Table: sp_summary scan count 1, logical reads: (regular=7457 apf=0
Table: Worktable1 scan count 1, logical reads: (regular=27000 apf=0
Re: неведоми са пътищата..
.... И тамън си го изтествал и изведнъж се оказва, че разпределението на стойностите вече е съвсем друго и всъщност е наопаки
Изобщо накрая опираш до Универсалния Отговор На Всички Въпроси Свързани С Бази Данни:
Зависи!
Бай Любо. Що по-често не се отбиваш тука а?
Изобщо накрая опираш до Универсалния Отговор На Всички Въпроси Свързани С Бази Данни:
Зависи!
Бай Любо. Що по-често не се отбиваш тука а?
Редактирано от salle на
Re: неведоми са пътищата..
1, 3, 2 не ми се вижда сортирано, поне не и по големина? 
"Да живееш - значи да се променяш." - Анатол Франс
"Да живееш - значи да се променяш." - Анатол Франс
Re: неведоми са пътищата..
GROUP BY винаги сортира в нарастващ ред. Ако искате да сортирате в намаляващ ред, коагто имате GROUP BY използвайте ORDER BY column_name DESC
Re: неведоми са пътищата..
говореше се по скоро за смисъла на двете
или Прилики и Разлики между GROUP и ORDER BY
salle.online.bg/sig
или Прилики и Разлики между GROUP и ORDER BY
salle.online.bg/sig
Re: DISTINCT vs GROUP BY
да си кажа и аз мнението :)
select distinct a, b from table
select a, b from table group by a, b
за SQL Server правят една и съща операция
->distinct order by a asc, b asc
така че би трябвало да са еднакво бързи и да върщат еднакъв по вид резултат
select distinct a, b from table
select a, b from table group by a, b
за SQL Server правят една и съща операция
->distinct order by a asc, b asc
така че би трябвало да са еднакво бързи и да върщат еднакъв по вид резултат
Re: DISTINCT vs GROUP BY
Да, но при DISCTINCT резултатът не е сортиран.
Т.е. ако не зададеш умишлено ORDER BY, нещата остават в този ред, в който върви и SELECT-а през редовете.
Т.е. ако не зададеш умишлено ORDER BY, нещата остават в този ред, в който върви и SELECT-а през редовете.
Re: DISTINCT vs GROUP BY
Когато напишеш SELECT DISTINCT a,b FROM table тогава резултата ти е всяка уникална двойка от (a,b),.
SELECT DISTINCT a FROM table
връща различен от
SELECT DISTINCT a,b FROM table
Докато за GROUP BY подобното е съвсем друго:
SELECT a,b,max(b) FROM table
GROUP BY a,b
ще групира редовете по колоната a, а след това за всяко различно а ще намери различните b. Следващото е ясно какво ще върне.
SELECT a,max(b) FROM table
GROUP BY a
Оказа се обаче, че и DISTINCT връща сортиран резултат в нарастващ ред. Така че грешката е моя в предното съобщение.
Така че определено това са две различни неща, като за DISTINCT не може да се каже, че е метод за групиране, а по-скоро начин за намиране на уникално множество да кажем.
Нали, salle?
SELECT DISTINCT a FROM table
връща различен от
SELECT DISTINCT a,b FROM table
Докато за GROUP BY подобното е съвсем друго:
SELECT a,b,max(b) FROM table
GROUP BY a,b
ще групира редовете по колоната a, а след това за всяко различно а ще намери различните b. Следващото е ясно какво ще върне.
SELECT a,max(b) FROM table
GROUP BY a
Оказа се обаче, че и DISTINCT връща сортиран резултат в нарастващ ред. Така че грешката е моя в предното съобщение.
Така че определено това са две различни неща, като за DISTINCT не може да се каже, че е метод за групиране, а по-скоро начин за намиране на уникално множество да кажем.
Нали, salle?
Re: DISTINCT vs GROUP BY
не съм съгласен
особено с
SELECT a,b,max(b) FROM table
не мисля, че когато имаме агрегатна функ.
GROUP BY и DISTINCT трябва да се сравняват, защото вече престават да правят едо и също
обаче в чистя случай кото го посочих по-горе са еднакви :)
Някой може ли да погледне плана двете на заявки за mysql или oracle за да направим сравнение
особено с
SELECT a,b,max(b) FROM table
не мисля, че когато имаме агрегатна функ.
GROUP BY и DISTINCT трябва да се сравняват, защото вече престават да правят едо и също
обаче в чистя случай кото го посочих по-горе са еднакви :)
Някой може ли да погледне плана двете на заявки за mysql или oracle за да направим сравнение
Re: DISTINCT vs GROUP BY
Съществуващите(въведените) уникални комбинации съдържащи се в дадено множество може би е по-правилно, не знам.
Re: DISTINCT vs GROUP BY
Аз ги гледам в Oracle и гарантирам че и без агрегатна функция връщат съвсем различни резултати. Едното групира, другото намира уникална комбинация или всички уникални стойности ако е по една колона само.
Re: DISTINCT vs GROUP BY
Логиката ти е обърната.
В ОБЩИЯ случай GROUP BY и DISTINCT са съвършено различни неща така както например в общия случай Вектор и Скалар и Матрица са съвсем различни.
В частен случай естествено матрица ( 1x1 ) е идентична на Скалар а също и на Вектор ( 1 )
Та и в тук е така.
В общия случай:
GROUP BY служи за Обобщаване, Групиране, Агрегиране по даден признак
DISTINCT служи за фирлтриране на уникалните РЕДОВЕ във крайния резултат
Затова и е напълно допустимо като синтаксис, макар и рядко да има логика да се използват и двете в една заявка. (В ANSI никога, в MySQL има приложение)
SELECT DISTINCT name, SUM(score) as total FROM tbl GROUP BY name;
Това би трябвало да изведе
Само Уникалните Комбинации Име, total ...което като се замислиш и тавталогия - те Вече са уникални по определение.
MySQL разширява ANSI като позволяви групиране по скрита колона т.е. такава, която липсва в SELECT частта и точно тогава DISTINCT може да придобие смисъл.
Такова използване на GROUP BY обаче е адски объркващо и трябва много да се внимава при ентерпретиране на резултатите.
И накрая.
Във всеки SQL сървър живее едно нещо което е доста близко до понятието Изкуствен Интелект.
Оптимизатора на заявки.
И тъй като неговата работа е да Предостави Крайния резултат - един хитър оптимизатор може да забалежи Частния случай и да използва по-ефективния алгоритъм - да представи Матрицата като Вектор или обратното.
Точно това прави оптимизатора на MySQL и това обърква доста хора когат прочитат документацията.
Dakota?
[линк]
DISTINCT is converted to a GROUP BY on all columns,
Та горното може да го приведеш по аналогия към примера когато Оптимизаторът решава да разглежда Вектор ( N ) като частен случай на Матрица ( N x 1 ) просто в случая този алгоритъм е ... ами по-общия
включва в себе си другия ...
Как може да се направи SELECT a, COUNT(*) GROUP BY на ръка:
За всяка Уникална стойност на a преравяш редовете и броиш колко пъти се среща.
Т.е. GROUP BY за да работи изобщо така и така трябва да изброи Уникалните (DISTINCT) стойности.
Наздраве
salle.online.bg/sig
В ОБЩИЯ случай GROUP BY и DISTINCT са съвършено различни неща така както например в общия случай Вектор и Скалар и Матрица са съвсем различни.
В частен случай естествено матрица ( 1x1 ) е идентична на Скалар а също и на Вектор ( 1 )
Та и в тук е така.
В общия случай:
GROUP BY служи за Обобщаване, Групиране, Агрегиране по даден признак
DISTINCT служи за фирлтриране на уникалните РЕДОВЕ във крайния резултат
Затова и е напълно допустимо като синтаксис, макар и рядко да има логика да се използват и двете в една заявка. (В ANSI никога, в MySQL има приложение)
SELECT DISTINCT name, SUM(score) as total FROM tbl GROUP BY name;
Това би трябвало да изведе
Само Уникалните Комбинации Име, total ...което като се замислиш и тавталогия - те Вече са уникални по определение.
MySQL разширява ANSI като позволяви групиране по скрита колона т.е. такава, която липсва в SELECT частта и точно тогава DISTINCT може да придобие смисъл.
Такова използване на GROUP BY обаче е адски объркващо и трябва много да се внимава при ентерпретиране на резултатите.
И накрая.
Във всеки SQL сървър живее едно нещо което е доста близко до понятието Изкуствен Интелект.
Оптимизатора на заявки.
И тъй като неговата работа е да Предостави Крайния резултат - един хитър оптимизатор може да забалежи Частния случай и да използва по-ефективния алгоритъм - да представи Матрицата като Вектор или обратното.
Точно това прави оптимизатора на MySQL и това обърква доста хора когат прочитат документацията.
Dakota?
[линк]
DISTINCT is converted to a GROUP BY on all columns,
Та горното може да го приведеш по аналогия към примера когато Оптимизаторът решава да разглежда Вектор ( N ) като частен случай на Матрица ( N x 1 ) просто в случая този алгоритъм е ... ами по-общия
Как може да се направи SELECT a, COUNT(*) GROUP BY на ръка:
За всяка Уникална стойност на a преравяш редовете и броиш колко пъти се среща.
Т.е. GROUP BY за да работи изобщо така и така трябва да изброи Уникалните (DISTINCT) стойности.
Наздраве
salle.online.bg/sig