Подтвердить что ты не робот

Почему COUNT() показывает только одну строку таблицы?

У меня есть следующая таблица pet в базе данных menagerie:

+--------+-------------+---------+------+------------+------------+
| name   | owner       | species | sex  | birth      | death      |
+--------+-------------+---------+------+------------+------------+
| Tommy  | Salman Khan | Lebre   | NULL | 1999-01-13 | 0000-00-00 |
| Bowser | Diane       | dog     | m    | 1981-08-31 | 1995-07-29 |
+--------+-------------+---------+------+------------+------------+

Теперь, если я запустил следующий запрос:

select owner, curdate() from pet;  

Я получаю следующий вывод:

+-------------+------------+
| owner       | curdate()  |
+-------------+------------+
| Salman Khan | 2016-09-12 |
| Diane       | 2016-09-12 |
+-------------+------------+

Вывод показывает все значения owner и значение, возвращаемое с curdate() в каждой строке.

Теперь, если я запустил следующий запрос:

select owner, count(*) from pet;  

Я получаю следующий вывод:

+-------------+----------+
| owner       | count(*) |
+-------------+----------+
| Salman Khan |        2 |
+-------------+----------+  

Мой вопрос в том, какая разница между curdate() и count() функцией, которая позволяет MySQL выводить вторую owner Diane в первом примере?

4b9b3361

Ответ 1

COUNT() - это функция агрегации, которая обычно объединяется с предложением GROUP BY.

curdate() - это функция даты, которая выводит текущую дату.

Только MySQL (насколько мне известно) допускает этот синтаксис без использования предложения GROUP BY. Поскольку вы не предоставили его, COUNT(*) будет считать общее количество строк в таблице, а столбец owner будет выбран случайным образом/оптимизатор по умолчанию/по индексам.

Это должен быть ваш запрос:

select owner, count(*) 
from pet
group by owner;

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

Если упомянутое предложение по группе не указано - функции агрегации применяются ко всем данным таблицы.

EDIT: Счет, который будет применяться к каждой строке, обычно не может выполняться с помощью COUNT() и обычно используется с аналитической функцией → COUNT() OVER(PARTITION...), которая, к сожалению, не существует в MySQL. Другой вариант - сделать JOIN/CORRELATED QUERY для этого дополнительного столбца.

Другое Редактировать: Если вы хотите подсчитать количество рядом с каждым владельцем, вы можете использовать дополнительный запрос:

SELECT owner,
       (SELECT COUNT(*) FROM pet) as cnt
FROM pet

Ответ 2

Это выглядит так же, как сценарий внизу этой страницы: Документация по MySQL: 4.3.4.8 Подсчет строк.

Если ONLY_FULL_GROUP_BY не включен, запрос обрабатывается обрабатывая все строки как одну группу, но значение, выбранное для каждого named column является неопределенным. Сервер может свободно выбирать значение из любой строки:

mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT owner, COUNT(*) FROM pet;
+--------+----------+
| owner  | COUNT(*) |
+--------+----------+
| Harold |        8 |
+--------+----------+
1 row in set (0.00 sec)

Я думаю, в этом случае only_full_group_by не установлен.

Ответ 3

Только MySQL позволит вам делать такие запросы.

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

Итак, вам это нужно:

SELECT owner, count(*) FROM pet GROUP BY owner;

Что приведет к:

Saknan Khan |  1
Diane       |  1

Это то, что вы намеревались достичь?

Или, может быть, вы попытались сделать это:

SELECT t.owner,
       COUNT(*) as cnt
FROM pet t
CROSS JOIN pet s
GROUP BY t.owner

Это приведет к дополнительному столбцу с общим количеством отсчетов рядом с каждым владельцем.

Ответ 4

Большинство систем СУБД не позволят агрегатной функции, такой как count(), с дополнительными столбцами без группы; по причине. СУБД не знает, какие столбцы группировать: -).

Решение состоит в том, чтобы сгруппировать запрос по столбцу владельца, например:

SELECT owner, count(*) FROM pet GROUP BY owner;

Ответ 5

Функция подсчета (*) агрегата возвращает только одно значение и т.е. общее количество строк. И функция curdate() просто предоставляет текущую дату системы.

Ответ 6

Последний запрос недействителен для Oracle: ORA-00937: не одногрупповая функция. Это означает, что вам нужно предложение GROUP BY. Вы нашли лазейку в реализации MySql. Не полагайтесь на такой запрос в производственной системе, в следующей версии MySql это может не сработать.

Ответ 7

Да, это обычно происходит с использованием предложения group by.

http://www.w3schools.com/sql/sql_groupby.asp Вы должны прочитать в ссылке все о предложении group by.

Все столбцы следует упомянуть либо в виде агрегации, либо в группе с помощью