как работает groupby и count в sql - PullRequest
3 голосов
/ 28 октября 2010

1> select browser,count(*) from logtest group by browser;

+-----------+----------+
| browser   | count(*) |
+-----------+----------+
| Firefox 3 |       14 |
| Unknown   |       11 |
+-----------+----------+

2 ряда в наборе

2> select browser,count(browser) from logtest group by browser;

+-----------+----------------+
| browser   | count(browser) |
+-----------+----------------+
| Firefox 3 |             14 |
| Unknown   |             11 |
+-----------+----------------+

2 ряда в наборе

3> select browser,count(browser) from logtest;

+-----------+----------------+
| browser   | count(browser) |
+-----------+----------------+
| Firefox 3 |             25 |
+-----------+----------------+

1 строка в наборе

Почему способ запроса 1> и 2> приводит к одинаковому результату? Нет ли разницы между количеством (*) и количеством (иногда)?

Кроме того, почему запросы 2> и 3> приводят к разным результатам, почему groupby такая волшебная? Как это работает?


UPDATE: Я использую MySQL5.1. :)

Ответы [ 5 ]

3 голосов
/ 28 октября 2010

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

Например, у вас естьТаблица с именем Животные со следующими полями:

Type | Gender | Name

Если вы выполняете этот запрос (например, в MySQL):

 select Type, Gender, Name from Animals where Type <> 'Pig'

вы получите всех животных, которые не являются«Свинья».Если строка имеет тип = 'pig', она будет включена в результаты.

Этот запрос:

select Type, Gender, count(*) from Animals group by Type, Gender

будет иметь столько строк: количество типов * количество полов

Вы можете создать условия для своей группы, используя в MySQL предложение «с».

Подробнее здесь

Разница между count(*) и count(browser) означает, что первая вернет номер всех записей, вторая вернет номер всех записей, где not (browser is null).

Попробуйте вставить строку, где browser is null, а затем выполните 1) и 2),это лучший тест.

2 голосов
/ 28 октября 2010

COUNT(*) обычно является сокращением для подсчета всех записей. Некоторые СУБД оптимизируют его, например таблицы MySQL MyISAM. В противном случае COUNT(column_name) не отличается для ненулевых значений.

Ваш третий запрос отличается тем, что вы продолжаете считать записи, но поскольку вы не группируете их по столбцу, вы получаете счетчик для всех записей. В вашем случае это не только Firefox 3 (14) и Unknown (11), что равно 25. Факт, который возвращает вашу верхнюю строку, является странным, и, как отметили другие пользователи, вероятно, не должен работать. В конечном счете, это сильно зависит от вашей РСУБД.

Не уверен, какую СУБД вы используете, но вы можете прочитать о GROUP BY здесь . В целом, хотя они чаще всего используются для поддержки агрегатных функций, таких как COUNT(), MAX(), AVG() и т. Д.

0 голосов
/ 28 октября 2010

Вы должны указать реализацию SQL или продукт, который вы используете, чтобы получить точный ответ. Это MySQL?

Это говорит:

Запросы 1 и 2 почти одинаковы. COUNT (*) добавит один к количеству для каждой строки в группе. COUNT (FieldName) будет добавлять 1 каждый раз, когда значение в FieldName не равно NULL. В вашем примере Browser никогда не имеет значение NULL, поэтому результат тот же.

Когда это может быть иначе? Если ваша таблица содержит 10 строк с NULL в поле браузера, первый запрос будет иметь дополнительную строку (NULL) | 10 и второй запрос будет сообщать (NULL) | 0.

Третий запрос не будет выполняться в некоторых реализациях SQL. Поскольку вы эффективно «GROUPing BY» всей таблицы, как база данных может определить, какое значение Browser следует поместить в первый столбец? Не может Некоторые реализации не будут запускать эти запросы, другие выберут, более или менее случайным образом, значение Browser (что вы и видите).

0 голосов
/ 28 октября 2010

COUNT(field) исключает нулевые значения.SQL Server также поддерживает некоторые дополнительные разновидности этой команды, но не уверен, являются ли они стандартными:

COUNT (*) возвращает количество элементов в группе, включая значения NULLи дубликаты.

COUNT (выражение ALL) оценивает выражение для каждой строки в группе и возвращает количество ненулевых значений.

COUNT (выражение DISTINCT) оценивает выражение для каждой строки в группе ивозвращает количество уникальных ненулевых значений.

Что касается вашего второго вопроса, groupby в основном говорит операторам агрегирования группировать их операции по определенному полю.Как вы заметили, если вы не укажете поле группировки, они будут действовать на всю таблицу. Немного больше от technet .

Я не уверен, что происходит с результатом 3, так как он не выглядит для меня правильным SQL.Как правило, вы не можете смешивать агрегации, такие как COUNT или AVG, с неагрегированными полями, если вы не группируете по этим полям.

0 голосов
/ 28 октября 2010

count(*) говорит, что считает все строки.count(browser) говорит, что нужно подсчитать все ненулевые значения браузера.Это может иметь существенное значение, особенно если у вас нет индекса в столбце браузера, поскольку тогда необходимо будет выполнить сканирование таблицы.

group by сегментирует ваш счет в соответствии с столбцами) указано.

...