una - view lenta mysql
¿Por qué COUNT() muestra solo una fila de tabla? (7)
Tengo la siguiente pet
mesa en la base de datos 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 |
+--------+-------------+---------+------+------------+------------+
Ahora si ejecuto la siguiente consulta:
select owner, curdate() from pet;
Me sale el siguiente resultado:
+-------------+------------+
| owner | curdate() |
+-------------+------------+
| Salman Khan | 2016-09-12 |
| Diane | 2016-09-12 |
+-------------+------------+
La salida muestra todos los valores de owner
y el valor devuelto de curdate()
en cada fila.
Ahora si ejecuto la siguiente consulta:
select owner, count(*) from pet;
Me sale el siguiente resultado:
+-------------+----------+
| owner | count(*) |
+-------------+----------+
| Salman Khan | 2 |
+-------------+----------+
Mi pregunta es ¿cuál es la diferencia entre las curdate()
y count()
que hacen que MySQL
curdate()
a la segunda owner
Diane en el primer ejemplo?
Esto se ve exactamente como el escenario al final de esta página: Documentación MySQL: 4.3.4.8 Recuento de filas .
Si ONLY_FULL_GROUP_BY no está habilitado, la consulta se procesa tratando todas las filas como un solo grupo, pero el valor seleccionado para cada columna nombrada es indeterminado. El servidor es libre de seleccionar el valor de cualquier fila:
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)
Supongo que en este caso no se establece only_full_group_by
.
La última consulta no es válida para Oracle: ORA-00937: no es una función de un solo grupo. Esto significa que necesita una cláusula GROUP BY. Encontraste una laguna en la implementación de MySql. No confíe en dicha consulta en un sistema de producción, en una próxima versión de MySql esto podría no funcionar.
La mayoría de los sistemas DBMS no permiten una función agregada como count () con columnas adicionales sin un grupo por; por una razón. El DBMS no sabe qué columnas agrupar :-).
La solución es agrupar su consulta por la columna del propietario, de esta manera:
SELECT owner, count(*) FROM pet GROUP BY owner;
Sí, esto suele suceder sin utilizar la cláusula group by.
http://www.w3schools.com/sql/sql_groupby.asp Debes leer en el enlace todo sobre el grupo por cláusula.
Toda la columna debe ser mencionada ya sea agregación o en grupo por
Solo MySQL te permitirá hacer este tipo de consultas.
Siempre debe especificar todas las columnas que no se combinan con una función de agregación en la cláusula GROUP BY
. De lo contrario, los datos se combinarán en 1 fila, con las columnas agregadas configuradas correctamente y todas las demás columnas seleccionadas al azar o con los índices.
Así que necesitas esto:
SELECT owner, count(*) FROM pet GROUP BY owner;
Lo que resultará:
Saknan Khan | 1
Diane | 1
¿Es esto lo que pretendías lograr?
O tal vez trataste de hacer esto:
SELECT t.owner,
COUNT(*) as cnt
FROM pet t
CROSS JOIN pet s
GROUP BY t.owner
Lo que dará como resultado una columna adicional con el recuento total al lado de cada propietario.
COUNT()
es una función de agregación que generalmente se combina con una cláusula GROUP BY
.
curdate()
es una función de fecha que genera la fecha actual.
Solo MySQL (que yo sepa) permite esta sintaxis sin usar la cláusula GROUP BY
. Como no lo proporcionó, COUNT(*)
contará la cantidad total de filas en la tabla, y la columna de owner
se seleccionará al azar / por defecto del optimizador / por los índices.
Esta debe ser su consulta:
select owner, count(*)
from pet
group by owner;
Lo que le dice al optimizador que cuente las filas totales, para cada propietario.
Cuando no se menciona una cláusula por grupo, las funciones de agregación se aplican a todos los datos de la tabla.
EDITAR: un conteo que se aplicará en cada fila no se puede hacer normalmente con COUNT()
y generalmente se usa con una función analítica -> COUNT() OVER(PARTITION...)
que desafortunadamente no existe en MySQL. Su otra opción es hacer una JOIN/CORRELATED QUERY
para esta columna adicional.
Otra edición: Si desea contar el total junto a cada propietario, puede usar una sub consulta:
SELECT owner,
(SELECT COUNT(*) FROM pet) as cnt
FROM pet
La función agregada Count (*) devuelve solo un valor y es decir, el número total de filas. Y la función curdate () es simplemente proporcionar la fecha actual del sistema.