2012-05-29 12 views
5

Lo necesito para fines de gráficos. Básicamente tengo que:¿Hay alguna forma de generar filas "falsas" en el conjunto de resultados de MySQL?

  1. Seleccionar todo enviado SMS por fecha sin parte de tiempo, obteniendo una matriz con fechas/cuentas pares día a día;
  2. Agregue filas "falsas" por días sin ningún registro en mi tabla, eso está llenando todas las fechas "huecos" con ceros.

Un resultado ejemplo y la tabla correspondiente (en este caso simplificado) sería:

array(
    '2012-05-26 00:00:00' => 1, 
    '2012-05-27 00:00:00' => 0, // Fake added row 
    '2012-05-28 00:00:00' => 2, 
) 

+----------------+----------------------+ 
| Table SMS | id | sent_at    | 
+----------------+----------------------+ 
|   | 1 | 2012-05-26 21:58:41 | 
+----------------+----------------------+ 
|   | 2 | 2012-05-28 22:19:21 | 
+----------------+----------------------+ 
|   | 3 | 2012-05-28 02:19:21 | 
+----------------+----------------------+ 

¿Hay alguna comandos SQL para hacer esto o debo hacer manualmente la reproducción con matrices de PHP?

+1

¿Cuál sería el razonamiento detrás de esto? –

+0

@ColeJohnson en algunas bibliotecas de gráficos, debe especificar marcas de tiempo (eje x) y valores (eje y) para obtener, por ejemplo, un gráfico de líneas. Como solo estoy almacenando mensajes de texto, necesito completar las fechas vacías. – gremo

+0

lo que hago para esto está en el ciclo while que crea la matriz, verifique que la fecha sea la siguiente de una serie de intervalos de fechas, e inserte según sea necesario. –

Respuesta

4

Se puede utilizar una declaración de la Unión

SELECT 
    sent_at, 
    Count(*) 
FROM (Select 
     id, 
     DATE(sent_at) as sent_at 
     FROM TableName 
     Group by Date(sent_at) 
     UNION ALL 
     Select 
     '0' as id, 
     DATE('2012-05-27') as sent_at) derived_table 
Group By sent_at 

Editado

he sugerido la creación de una mesa especial para unirse en contra.

Creación de un datetable para consultar

CREATE TABLE DateTable (
    DateValue DateTime, 
    Year Int, 
    Month Int, 
    Day Int) 

Ahora llenar esta tabla con todos los valores de fecha dentro de los rangos que está consultando. Puede unirse fácilmente a esta tabla con cualquier fecha válida. Permitiéndole agregar fechas que existen y no existen.

+2

Corrígeme si estoy equivocado, pero esto agregaría solo una fila al conjunto de resultados. Tengo que llenar "huecos" entre todas las fechas. – gremo

+1

@gremo si quieres contar todas las fechas específicas, entonces necesitarás usar una tabla derivada con las "filas falsas" que has agregado (que conforman las lagunas). Si desea que las lagunas se llenen dinámicamente, le sugiero que cree una tabla de fechas para usted mismo, que incluirá todas las fechas para un período de tiempo específico. Luego únete a esta tabla para obtener las fechas faltantes. –

1

Sí, hago esto todo el tiempo

DROP PROCEDURE IF EXISTS `Example`; 
DELIMITER $$ 

CREATE PROCEDURE `Example` (
    $StartDate DATE, 
    $EndDate DATE 
    ) 
BEGIN 

    DECLARE $curDay DATE; 
    SET $StartDate = IFNULL($StartDate,'2000-01-01'); 
    SET $curDay = $StartDate; 


    DROP TEMPORARY TABLE IF EXISTS `Day`; 
    CREATE TEMPORARY TABLE `Day`(
     `Date` DATE 
    ); 

    DaysLoop:LOOP 

     INSERT INTO 
      `Day`(`Date`) 
     SELECT 
      $curDay 
     ; 

     SET $curDay = $curDay + INTERVAL 1 DAY; 

     IF 
      $curDay >= $EndDate OR $curDay >= NOW() 
     THEN 
      LEAVE DaysLoop; 
     END IF; 

    END LOOP DaysLoop; 

    SELECT 
     D.Date, 
     COUNT(S.id) 
    FROM 
     `Day` AS D 
    LEFT JOIN 
     `SMS` AS S 
     ON D.Date = DATE(S.sent_at) 
    GROUP BY 
     D.Date 
    ORDER BY 
     D.Date 
    ; 

END $$ 

DELIMITER ; 

CALL Example('2012-01-01','2012-05-01'); 

yo uso y recomiendo procedimientos almacenados para los informes, sólo asegúrese de que el control de la versión de crear secuencias de comandos y otras cosas.

+0

Ah, y usted no tiene que tener el 'group by', o se puede agrupar por DAY_HOUR, etc. – KCD

Cuestiones relacionadas