mysql sql database rdbms

suma de conteo(*) para todas las filas en MySQL



database rdbms (9)

Estoy atascado con la consulta sum() donde quiero que la suma de los valores de count(*) en todas las filas con group by .

Aquí está la consulta:

select u.user_type as user, u.count, sum(u.count) FROM ( select DISTINCT user_type, count(*) as count FROM users where (user_type = "driver" OR user_type = "passenger") GROUP BY user_type ) u;

Salida de corriente:

---------------------------------- | user | count | sum | ---------------------------------- | driver | 58 | 90 | ----------------------------------

Rendimiento esperado:

---------------------------------- | user | count | sum | ---------------------------------- | driver | 58 | 90 | | passenger | 32 | 90 | ----------------------------------

Si sum(u.count) de la consulta, la salida se sum(u.count) así:

-------------------------- | user | count | -------------------------- | driver | 58 | | passenger | 32 | --------------------------


Agregue una cláusula group by al final para user-type de user-type , por ejemplo:

select u.user_type as user, u.count, sum(u.count) FROM ( select DISTINCT user_type, count(*) as count FROM users where (user_type = "driver" OR user_type = "passenger") GROUP BY user_type ) u GROUP BY u.user_type;


Estaría tentado de preguntar; ¿Estás seguro de que necesitas esto en el nivel de DB?

A menos que esté trabajando puramente en la capa de base de datos, cualquier procesamiento de estos resultados se integrará en una capa de aplicación y presumiblemente requerirá algún tipo de bucle a través de los resultados

Podría ser más fácil, más simple y más fácil de ejecutar

SELECT user_type, COUNT(*) AS count FROM users WHERE user_type IN ("driver", "passenger") GROUP BY user_type

.. y simplemente sume el recuento total en la capa de aplicación

Como lo señaló Juan en otra respuesta, DISTINCT es redundante, ya que GROUP BY garantiza que cada fila resultante sea diferente

Al igual que Juan, también prefiero una IN aquí, en lugar de una condición OR, para el tipo_usuario ya que me resulta más legible. También reduce la posibilidad de confusión si se combinan condiciones adicionales en el futuro.

Además, consideraría mover los nombres de los tipos de usuario, "conductor" y "pasajero" a una tabla separada de tipos de usuarios y hacer referencia a ellos mediante una columna de ID de su tabla de usuarios

NB: Si realmente necesita esto a nivel de base de datos, recomendaría el uso de una de las excelentes opciones de Paul, o el enfoque CROSS JOIN ofrecido por Tom Mac y por Juan como su segunda solución sugerida


Necesitas una subconsulta:

SELECT user_type, Count(*) AS count, (SELECT COUNT(*) FROM users WHERE user_type IN ("driver","passenger" )) as sum FROM users WHERE user_type IN ("driver","passenger" ) GROUP BY user_type ;

Tenga en cuenta que no necesita distinct aquí.

O

SELECT user_type, Count(*) AS count, c.sum FROM users CROSS JOIN ( SELECT COUNT(*) as sum FROM users WHERE user_type IN ("driver","passenger" ) ) as c WHERE user_type IN ("driver","passenger" ) GROUP BY user_type ;


Prueba esto. La vista en línea obtiene el total general:

SELECT a.user_type, count(*) AS count, b.sum FROM users a JOIN (SELECT COUNT(*) as sum FROM users WHERE user_type IN ("driver","passenger" ) ) b ON TRUE WHERE a.user_type IN ("driver","passenger" ) GROUP BY a.user_type;


Prueba esto:

WITH SUB_Q AS ( SELECT USER_TYPE, COUNT (*) AS CNT FROM USERS WHERE USER_TYPE = "passenger" OR USER_TYPE = "driver" GROUP BY USER_TYPE ), SUB_Q2 AS ( SELECT SUM(CNT) AS SUM_OF_COUNT FROM SUB_Q ) SELECT A.USER_TYPE, A.CNT AS COUNT, SUB_Q2 AS SUM FROM SUB_Q JOIN SUB_Q2 ON (TRUE);

Usé el dialecto postgresql pero puede cambiar fácilmente a una subconsulta.


Puedes usar el modificador WITH ROLLUP :

select coalesce(user_type, ''total'') as user, count(*) as count from users where user_type in (''driver'', ''passenger'') group by user_type with rollup

Esto devolverá la misma información pero en un formato diferente:

user | count ----------|------ driver | 32 passenger | 58 total | 90

db-fiddle

En MySQL 8 puedes usar COUNT() como función de ventana :

select distinct user_type, count(*) over (partition by user_type) as count, count(*) over () as sum from users where user_type in (''driver'', ''passenger'');

Resultado:

user_type | count | sum ----------|-------|---- driver | 32 | 90 passenger | 58 | 90

db-fiddle

o use CTE (Expresiones de tabla comunes) :

with cte as ( select user_type, count(*) as count from users where user_type in (''driver'', ''passenger'') group by user_type ) select user_type, count, (select sum(count) from cte) as sum from cte

db-fiddle


Simplemente puede combinar SUM() OVER() con COUNT(*) :

SELECT user_type, COUNT(*) AS cnt, SUM(COUNT(*)) OVER() AS total FROM users WHERE user_type IN (''driver'', ''passenger'') GROUP BY user_type;

db <> fiddle demo

Salida:

+------------+------+-------+ | user_type | cnt | total | +------------+------+-------+ | passenger | 58 | 90 | | driver | 32 | 90 | +------------+------+-------+


Tom Mac Explica correctamente tu respuesta. Aquí está la otra forma en que puedes hacer eso. Verifico el rendimiento de la consulta y no encontré ninguna diferencia dentro de 1000 registros

select user_type,Countuser,(SELECT COUNT(*) FROM users WHERE user_type IN (''driver'',''passenger '') )as sum from ( select user_type,count(*) as Countuser from users a where a.user_type=''driver'' group by a.user_type union select user_type,count(*) as Countuser from users b where b.user_type=''passenger'' group by b.user_type )c group by user_type,Countuser


select u.user_type as user, u.count, sum(u.count) FROM users group by user