2016-04-24 4 views
-1

Может кто-нибудь объяснить, почему следующий запрос вызывает ошибку, если я пытаюсь получить имена всех клиентов вместе с общим количеством клиентов?Причина ошибки при использовании оператора select, содержащего агрегатные функции?

SELECT name, COUNT(*) 
FROM CUSTOMER 

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

редактировать:

http://sqlfiddle.com/#!2/90233/595 Я думаю, «ошибка» не совсем правильно, но обратите внимание, как текущий запрос возвращает Allison 9 в качестве единственного результата. я не понимаю, почему он не возвращается:

Alison 9

Alison 9

Alison 9

Alison 9

Jason 9

...

+0

Какая ошибка? – nicomp

+1

Предположительно, вы используете SQL Server. В своей конфигурации по умолчанию MySQL не генерирует ошибку. –

+0

Фактически я верю, что это вернет общий счет вместе с именем первого клиента. Нам нужен полный список имен клиентов, каждый из которых совпадает с общим количеством клиентов. Поэтому я не понимаю, почему полный список имен пользователей рушится при использовании совокупности Count – nsledeski

ответ

0

(Это новый ответ, основанный на комментарии и глядя на скрипку.)

Проблема здесь в том, как MySQL обрабатывает агрегатные функции - которая является нестандартным способом и отличается, то все остальные.

mysql позволяет использовать агрегатные функции (count() является примером агрегатной функции) без группы. Для всех (или большинства?) Других реализаций sql требуется группа, когда вы используете count (*). Когда у вас есть группа, вы должны сказать диапазон в группе (например, по имени). Также каждый столбец должен находиться в диапазоне или в результате функции агрегата.

СКОЛЬКО у вас нет диапазона mysql принимает всю таблицу, и поскольку у вас есть столбец, который не является результатом агрегатной функции или диапазона (в этом случае имя), mysql делает что-то, чтобы сделать этот столбец результат совокупной функции. Я не уверен, что в mysql указано, что он делает - скажем, «max()». (Достаточно уверен, что это max()). Таким образом, реальный sql, который выполняется, составляет

SELECT ANY_VALUE(name), COUNT(*) 
FROM CUSTOMER 

Таким образом, вы видите только одно имя.

MySQL документация - http://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

После прочтения выше, я вижу, что MySQL будет использовать функцию ANY_VALUE() агрегированных по умолчанию для столбцов, которые не находятся в диапазоне.


Если вы просто хотите, общее количество клиентов по каждой строке вы могли бы сделать это

SELECT DISTINCT NAME, COUNT(NAME) OVER() AS CustomerCount 
FROM CUSTOMER 

В этом случае вам не понадобится GROUP BY синтаксиса. Под обложками он, вероятно, делает то же самое, что и ответ @GordonLinoff.

Я добавил это, потому что, возможно, он разъясняет, как работает группа.

+0

еще раз, мой вопрос в том, почему мой запрос возвращает «Элисон 9», а не полный список имен, каждый из которых имеет общее количество строк. – nsledeski

+0

@nsledeski - Я понимаю, ваш вопрос сейчас см. Редактировать – Hogan

+0

замечательный ответ, большое спасибо! – nsledeski

0
Select name, Count(*) as 'CountCustomers' 
FROM CUSTOMER 
Group by name 
Order by name 

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

Кроме того, обратите внимание, что вы можете иметь несколько агрегатных функций в то же выбрать с помощью «над (раздел,» конструкт.

+0

. Это неправильно, это даст количество строк, которые данный клиент имеет в таблице, - именно та проблема, которую ОП просил решить. – Hogan

0

Если вы хотите имена наряду с общего числа клиентов, а затем использовать окно функция:

select name, count(*) as NumCustomersWithName, 
     sum(count(*)) over() as NumCustomers 
from customer 
group by name; 

Edit:

Вы на самом деле, кажется, хотят:

select name, count(*) over() as NumCustomers 
from customer; 

В MySQL, вы могли бы сделать это с помощью подзапроса:

select name, cnt 
from customers cross join 
    (select count(*) as cnt from customers) x; 

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

+0

Мой вопрос не о том, как найти правильный результат, поэтому мой оригинальный код возвращает неправильный – nsledeski

+0

@nsledeski. , , Какой результат вы действительно хотите? Образцы данных и желаемые результаты помогают. –

+0

Извините, я обновил сообщение на примере! – nsledeski

Смежные вопросы