2010-03-19 17 views
8

Tengo tabla de MySQLMySQL: llenar los campos vacíos con ceros cuando se utiliza GROUP BY

CREATE TABLE cms_webstat (
    ID int NOT NULL auto_increment PRIMARY KEY, 
    TIMESTAMP_X timestamp DEFAULT CURRENT_TIMESTAMP, 
    # ... some other fields ... 
) 

que contiene estadísticas sobre los visitantes del sitio.
Para conseguir visitas por hora utilizo

SELECT 
    hour(TIMESTAMP_X) as HOUR 
    , count(*) AS HOUR_STAT 
FROM cms_webstat 
GROUP BY HOUR 
ORDER BY HOUR DESC 

que me da

| HOUR | HOUR_STAT | 
| 24 | 15  | 
| 23 | 12  | 
| 22 | 9  | 
| 20 | 3  | 
| 18 | 2  | 
| 15 | 1  | 
| 12 | 3  | 
| 9 | 1  | 
| 3 | 5  | 
| 2 | 7  | 
| 1 | 9  | 
| 0 | 12  | 

Y me gustaría llegar siguientes:

| HOUR | HOUR_STAT | 
| 24 | 15  | 
| 23 | 12  | 
| 22 | 9  | 
| 21 | 0  | 
| 20 | 3  | 
| 19 | 0  | 
| 18 | 2  | 
| 17 | 0  | 
| 16 | 0  | 
| 15 | 1  | 
| 14 | 0  | 
| 13 | 0  | 
| 12 | 3  | 
| 11 | 0  | 
| 10 | 0  | 
| 9 | 1  | 
| 8 | 0  | 
| 7 | 0  | 
| 6 | 0  | 
| 5 | 0  | 
| 4 | 0  | 
| 3 | 5  | 
| 2 | 7  | 
| 1 | 9  | 
| 0 | 12  | 

Cómo debería modificar la consulta para obtener tal resultado (con una consulta mysql, sin crear tablas temporales)?
¿Es posible obtener ese resultado con una consulta MySQL?

+0

SaltLake, ¿crees que vas a aceptar una respuesta? –

+0

Marcus, su solución funciona pero no de la manera que yo quiero. Estoy interesado en la solución con una consulta SQL y sin crear y llenar otras tablas. – SaltLake

Respuesta

4

Finalmente encontré la respuesta. Tal vez estoy loco, pero esto funciona.

 
SELECT HOUR, max(HOUR_STAT) as HOUR_STAT FROM (
    (
     SELECT HOUR(TIMESTAMP_X) as HOUR, count(*) as HOUR_STAT 
     FROM cms_webstat 
     WHERE date(TIMESTAMP_X) = date(now()) 
    ) 
    UNION (SELECT 0 as HOUR, 0) 
    UNION (SELECT 1 as HOUR, 0) 
    UNION (SELECT 2 as HOUR, 0) 
    UNION (SELECT 3 as HOUR, 0) 
    UNION (SELECT 4 as HOUR, 0) 
    UNION (SELECT 5 as HOUR, 0) 
    UNION (SELECT 6 as HOUR, 0) 
    UNION (SELECT 7 as HOUR, 0) 
    UNION (SELECT 8 as HOUR, 0) 
    UNION (SELECT 9 as HOUR, 0) 
    UNION (SELECT 10 as HOUR, 0) 
    UNION (SELECT 11 as HOUR, 0) 
    UNION (SELECT 12 as HOUR, 0) 
    UNION (SELECT 13 as HOUR, 0) 
    UNION (SELECT 14 as HOUR, 0) 
    UNION (SELECT 15 as HOUR, 0) 
    UNION (SELECT 16 as HOUR, 0) 
    UNION (SELECT 17 as HOUR, 0) 
    UNION (SELECT 18 as HOUR, 0) 
    UNION (SELECT 19 as HOUR, 0) 
    UNION (SELECT 20 as HOUR, 0) 
    UNION (SELECT 21 as HOUR, 0) 
    UNION (SELECT 22 as HOUR, 0) 
    UNION (SELECT 23 as HOUR, 0) 
) 
AS `combined_table` 
GROUP BY HOUR 
ORDER BY HOUR DESC 

Una consulta de MySQL como desee.

8

Crear otra tabla con una sola columna,

CREATE TABLE hours_list (
    hour int NOT NULL PRIMARY KEY 
) 

llenarlo con los 24 horas.

Luego haga una combinación en esa tabla para completar los ceros.

SELECT 
    hs.hour as HOUR, COUNT(ws.ID) AS HOUR_STAT 
FROM hours_list hs 
LEFT JOIN cms_webstat ws ON hs.hour = hour(ws.TIMESTAMP_X) 
GROUP BY hs.hour 
ORDER BY hs.hour DESC 
3

Esta es solo la parte 'por qué no regresa'. La respuesta de Marcus cubre la parte de 'cómo hacerlo'.

El SQL

SELECT 
    hour(TIMESTAMP_X) as HOUR 
    , count(*) AS HOUR_STAT 
FROM cms_webstat 
GROUP BY HOUR 
ORDER BY HOUR DESC 

Obtiene el recuento de los registros por hora, para las marcas de tiempo presentes en la mesa

No da los detalles de lo que no está presente en la tabla. Dado que no hay recors para la marca de tiempo correspondiente a la hora 8 (de su ejemplo), el SQL no devuelve ningún registro.

0
$sql = 'SELECT g, MAX(v) AS v, MAX(c) AS c FROM ('; 
$sql .= '(SELECT DATE_FORMAT(viewed, \'%d.%m.%Y\') AS g, COUNT(1) AS v, 0 AS c FROM '.$this->prefix.'view WHERE campaignid IN ('.join(', ',$ids).') GROUP BY g)'; 
$sql .= ' UNION (SELECT DATE_FORMAT(clicked, \'%d.%m.%Y\') AS g, 0 AS v, COUNT(1) AS c FROM '.$this->prefix.'clicks WHERE campaignid IN ('.join(', ',$ids).') GROUP BY g)'; 
$today = strtotime("00:00:00"); 
for ($i=$today; $i>=time()-30*86400; $i-=86400) { 
    $sql .= ' UNION (SELECT \''.date('d.m.Y',$i).'\' AS g, 0 AS v, 0 AS c)'; 
} 
$sql .= ') AS tmp GROUP BY g ORDER BY g DESC'; 

$chart = DB::getAll($sql); 
p($chart); 

Gracias! Hecho! A partir de 2 tablas, clics y vistas, se unió a ... funciona. ajaxel.com