2012-08-22 6 views
5

Duplicar posible:
Calculate a running total in MySQLMySQL agregada por mes con el funcionamiento total de

Estoy controlar el número de usuarios creados desde 2011 en una aplicación por mes para un gráfico utilizando MySQL y PHP. Como parte de la consulta, también me gustaría incluir un total acumulado.

SELECT 
    DATE_FORMAT(created,'%Y%m%d') as 'Date', 
    COUNT(item_id) as 'NewUsers' 
FROM AP_user 
WHERE YEAR(created) > 2011 
    AND user_groups = '63655' 
    AND user_active = 1 
    AND userID NOT IN $excludedUsers 
GROUP BY MONTH(created) ASC 

soy capaz de devolver los "usuarios por mes", pero ¿Cómo puedo incluir un total de ejecución como parte de esta consulta?

+1

Necesitará una subconsulta. Agrégalo a tu selección y llámalo total. 'SELECCIONAR (SELECCIONAR" obtener el total aquí ") como total' O en PHP simplemente sume el total de cada mes. –

+0

Agregué la siguiente subconsulta y parece que MySQL no me gusta: 'SELECT (SELECT COUNT (item_id) FROM AP_user WHERE YEAR (created)> 2011 AND user_groups = '63655' AND user_active = 1 AND userID NOT IN $ excludedUsers) como 'TotalUsers' DATE_FORMAT (creado, '% Y% m% d') como 'Fecha', COUNT (item_id) como 'NewUsers' DE AP_user WHERE YEAR (creado)> 2011 AND user_groups = '63655' AND user_active = 1 Y userID NOT IN $ excludedUsers GROUP BY MONTH (creado) ASC' – Bill

+0

No importa, me falta una coma ... gracias. – Bill

Respuesta

6

Desafortunadamente, MySQL no proporciona funciones analíticas, como lo hacen Oracle y SQL Server.

Una forma de obtener una "total acumulado" es hacer uso de una variable de usuario, algo como esto:

SELECT t.Date 
     , t.NewUsers 
     , @rt := @rt + t.NewUsers AS `Running Total` 
    FROM (SELECT @rt := 0) i 
    JOIN (
      SELECT DATE_FORMAT(created,'%Y%m%d') AS `Date` 
       , COUNT(item_id) as `NewUsers` 
      FROM AP_user 
      WHERE YEAR(created) > 2011 
       AND user_groups = '63655' 
       AND user_active = 1 
       AND userID NOT IN $excludedUsers 
      GROUP BY DATE_FORMAT(created,'%Y-%m') 
      ORDER BY DATE_FORMAT(created,'%Y-%m') ASC 
     ) t 

NOTA: El comportamiento de las variables de memoria como se ha usado anteriormente no está garantizado en este contexto. Pero si somos cuidadosos con la consulta, podemos obtener resultados predecibles y repetibles en las instrucciones SELECT. El comportamiento de las variables de memoria puede cambiar en una versión futura, haciendo que este enfoque sea inviable.

NOTA: Básicamente envolví su consulta entre paréntesis, y le di un alias como una vista en línea (lo que MySQL llama una "tabla derivada"). Hice algunos cambios a su consulta, su GROUP BY tiene potencial para agrupar enero de 2012 junto con enero de 2013, lo cambié. También agregué una cláusula ORDER BY.

+0

Necesito "," después de "creado" en las secciones Ordenar y Agrupar por, pero aparte de eso, funciona muy bien, ¡gracias! – Bill

+0

Debido a la naturaleza compleja de los requisitos de la pregunta, la respuesta es difícil de entender. Sin embargo, gran trabajo @ spencer7593. gracias a la pregunta también. He votado por ambos. Lo usaré en el futuro. No esperaba que se pudiera solucionar en una sola consulta – Sami

+1

@Sami Akram: está en lo cierto, no es realmente solucionable en una "única consulta", en el sentido de que mi solución básicamente obliga a MySQL a ejecutar una subconsulta para materializar una vista en línea (o "tabla derivada" en jerga MysQL), y luego la consulta externa se ejecuta en contra de eso. Podemos hacer todo en un único SELECT, pero estamos (efectivamente) haciendo que MySQL ejecute dos consultas para nosotros. – spencer7593

Cuestiones relacionadas