2010-03-19 16 views
8

Ich habe Tabelle MySQLMySQL: leere Felder mit Nullen füllen, wenn GROUP BY mit

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

, die Statistiken über Besucher der Website enthält.
Für Besuche pro Stunde bekomme ich verwenden

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

die mich

| 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  | 

gibt Und ich würde folgendes bekommen:

| 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  | 

Wie soll ich die Abfrage ändern zu bekommen solches Ergebnis (mit einer MySQL-Abfrage, ohne temporäre Tabellen zu erstellen)?
Ist es möglich, ein solches Ergebnis mit einer MySQL-Abfrage zu erhalten?

+0

SaltLake, glaubst du, du wirst eine Antwort akzeptieren? –

+0

Marcus, deine Lösung funktioniert, aber nicht so, wie ich es möchte. Ich bin an einer Lösung mit einer SQL-Abfrage interessiert und ohne weitere Tabellen zu erstellen und zu füllen. – SaltLake

Antwort

4

Ich habe endlich die Antwort gefunden. Vielleicht bin ich verrückt, aber das funktioniert.

 
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 

Eine MySQL-Abfrage wie gewünscht.

8

Erstellen Sie eine andere Tabelle mit einer einzigen Spalte,

CREATE TABLE hours_list (
    hour int NOT NULL PRIMARY KEY 
) 

Füllen Sie ihn mit allen 24 Stunden.

Dann machen Sie einen Beitritt auf dieser Tabelle, um die Nullen zu füllen.

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

Dies ist nur der 'warum es nicht zurückkehrt' Teil. Marcus 'Antwort deckt das "wie" ab.

Die SQL

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

wird die Anzahl der Datensätze pro Stunde, für die gegenwärtigen Zeitstempel in der Tabelle

Es gibt nicht die Details von dem, was in der Tabelle nicht vorhanden ist. Da für den Zeitstempel, der der Stunde 8 (aus Ihrem Beispiel) entspricht, kein Recor vorhanden ist, gibt das SQL keine Datensätze zurück.

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); 

Vielen Dank! Machte es! Von 2 Tabellen, Klicks und Ansichten, verbunden .. funktioniert. ajaxel.com