Самс научи себя SQL за 10 минут - Вопрос о GROUP BY - PullRequest
2 голосов
/ 18 января 2011

Я прочитал книгу «Самс научи себя SQL за 10 минут, третье издание» и в уроке 10 «Группировка данных», раздел «Создание групп», я не могу понять следующее:

" Помимо сводных операторов вычислений, каждый столбец в вашем операторе SELECT должен присутствовать в предложении GROUP BY. "

Почему? Я попробовал это, и я думаю, что это не так. Например, рассмотрим таблицу «Мир» со столбцами «континент», «страна», «население».

SELECT continent, country
FROM World
GROUP BY continent;

Согласно книге, это должно привести к ошибке, верно? Но это не так. Я могу сгруппировать свои данные в зависимости от континента (таким образом, мы имеем по результатам 7 континентов) и рядом с каждым континентом случайное название страны.

Как это

continent         country
North America     Canada
South America     Brazil
Europe            France
Africa            Cameroon
Asia              Japan
Australia         New Zealand
Antarctica        TuxLand

Ответы [ 3 ]

4 голосов
/ 18 января 2011

Скорее всего, вы используете MySQL, который допускает разгруппированные и неагрегированные выражения в предложении SELECT.

Это, конечно, нарушение стандарта.

Это предназначено для упрощения GROUP BY с объединениями на PRIMARY KEY:

SELECT  a.*, SUM(b.value)
FROM    a
JOIN    b
ON      b.a_id = a.id
GROUP BY
        a.id

Обычно вам нужно будет либо добавить все столбцы из a в предложение GROUP BY, либо использовать подзапрос.

MySQL позволяет вам этого не делать, поскольку все значения из a гарантированно будут одинаковыми для данного значения PRIMARY KEY (которое сгруппировано).

0 голосов
/ 18 января 2011

GROUP BY перечислит первый результат из указанных столбцов - поэтому в вашем случае будет возвращена первая пара страна / континент.

PostgreSQL и MySQL позволяют это, используя одно поле для группы.

В этом руководстве, вероятно, предполагается, что вы должны использовать GROUP BY во всех полях, поэтому из того, что вы выбрали, вы не потеряете никакие данные - в нем будет показана каждая страна / континент в приведенном выше примере, но только один раз.

Вот пример таблицы:

Continent      |  Country     | Random_Field
---------------------------------------------
North America     Canada          Cake
North America     Canada          Dog
South America     Brazil          Cat
Europe            France          Frog
Africa            Cameroon        House
Asia              Japan           Gadget
Asia              India           Dance
Australia         New Zealand     Frodo
Antarctica        TuxLand         Linux

В вашем первом утверждении:

SELECT continent, country
FROM World
GROUP BY continent;

Вывод будет:

Continent      |  Country     
--------------------------
North America     Canada   
South America     Brazil 
Europe            France  
Africa            Cameroon   
Asia              Japan    
Australia         New Zealand 
Antarctica        TuxLand  

Обратите внимание, что один из рядов Азии был потерян, несмотря на то, что он другой.

Использование GROUP BY на обоих:

SELECT continent, country
FROM World
GROUP BY continent, country;

даст:

   Continent      |  Country     
    -----------------------------
    North America     Canada   
    South America     Brazil    
    Europe            France    
    Africa            Cameroon    
    Asia              Japan      
    Asia              India      
    Australia         New Zealand 
    Antarctica        TuxLand 
0 голосов
/ 18 января 2011

Это правильно и не должно вызывать ошибок в некоторых формах SQL, таких как MySQL. При желании вы можете использовать оператор GROUP BY для нескольких столбцов, но это не обязательно.

...