2009-03-17 5 views
0

Ich muss mit einem Analysetool arbeiten, das die Web-Service-Aufrufe an einen Server pro Stunde misst. Diese Messungen werden in eine Datenbank eingefügt. Im Folgenden ist ein Ausschnitt aus einer solchen Messung:SQL/MySQL SELECT und Durchschnitt über bestimmte Werte

mysql> SELECT * FROM sample s LIMIT 4; 
+---------+------+-------+ 
| service | hour | calls | 
+---------+------+-------+ 
| WS04 | 04 | 24 | 
| WS12 | 11 | 89 | 
| WSI64 | 03 | 35 | 
| WSX52 | 01 | 25 | 
+---------+------+-------+ 
4 rows in set (0.00 sec) 

Als Endergebnis Ich mag würde die Summe aller Web-Services Beendigungen pro Stunde von Tag kennen.

mysql> SELECT hour, SUM(calls) FROM sample s GROUP BY hour; 
+------+------------+ 
| hour | SUM(calls) | 
+------+------------+ 
| 00 |  634 | 
| 01 |  642 | 
| 02 |  633 | 
| 03 |  624 | 
| 04 |  420 | 
| 05 |  479 | 
| 06 |  428 | 
| 07 |  424 | 
| 08 |  473 | 
| 09 |  434 | 
| 10 |  485 | 
| 11 |  567 | 
| 12 |  526 | 
| 13 |  513 | 
| 14 |  555 | 
| 15 |  679 | 
| 16 |  624 | 
| 17 |  796 | 
| 18 |  752 | 
| 19 |  843 | 
| 20 |  827 | 
| 21 |  774 | 
| 22 |  647 | 
| 23 |  533 | 
+------+------------+ 
12 rows in set (0.00 sec) 

Mein Problem ist, dass in der alten Sätzen, die Web-Service-Anrufe in den Stunden von [00-11] wurden bereits zusammengefasst: Offensichtlich kann dies leicht mit SUM() und GROUP BY erfolgen. Die einfache Aussage wie oben aufgeführt würde daher zu

mysql> SELECT hour, SUM(calls) FROM sample s GROUP BY hour; 
+------+------------+ 
| hour | SUM(calls) | 
+------+------------+ 
| 00 |  6243 | <------ sum of hours 00-11! 
| 12 |  526 | 
| 13 |  513 | 
| 14 |  555 | 
| 15 |  679 | 
| 16 |  624 | 
| 17 |  796 | 
| 18 |  752 | 
| 19 |  843 | 
| 20 |  827 | 
| 21 |  774 | 
| 22 |  647 | 
| 23 |  533 | 
+------+------------+ 
13 rows in set (0.00 sec) 

führen. Dies ist ein unerwünschtes Ergebnis. Um die alten Mengen [00,12, ..., 23] mit den neuen Mengen [00,01, ..., 23] vergleichbar zu machen, hätte ich gern eine Aussage, die den Wert von [00] mittelt und verteilt über die fehlenden Stunden, zB:

+------+------------+ 
| hour | SUM(calls) | 
+------+------------+ 
| 00 | 6243/11 | 
| 01 | 6243/11 | 
      [...] 
| 12 |  526 | 
      [...] 
| 23 |  533 | 
+------+------------+ 

ich kann dies unter Verwendung von temporären Tabellen oder Ansichten leicht tun, aber ich weiß nicht, wie diese, ohne sie zu erreichen.

Irgendwelche Ideen? Denn das macht mich verrückt: P

+0

Vermutlich müssen Sie 00..11 die 6243 Anrufe über die 12 Stunden verteilen, indem durch 12 dividiert, anstatt Teilen durch 11. –

Antwort

1

Sie benötigen ein Rowset mit 12 Zeilen, um eine Verknüpfung zu erstellen.

Die einfachste Lösung wird in einer Vereinigung 12 SELECT Aussagen werden kombiniert:

SELECT COALESCE(morning.hour, sample.hour), 
     SUM(CASE WHEN morning.hour IS NULL THEN calls ELSE calls/12 END) AS calls 
FROM sample 
LEFT JOIN 
     (
     SELECT 0 AS hour 
     UNION ALL 
     SELECT 1 
     ... 
     UNION ALL 
     SELECT 11 
     ) AS morning 
ON  sample.hour = 0 AND sample.service IN ('old_service1', 'old_service2') 
GROUP BY 
     1 
+0

Einige der Daten haben tatsächliche Werte für Stunden 0, 1, .. 11, also müssen Sie die Verteilung durchführen, wenn keine Daten für die fehlenden Stunden vorhanden sind. –

+0

Aktualisiert, um damit umzugehen. – Quassnoi

1

Sie sind wahrscheinlich am besten mit temp Tabellen/Ansichten (ich würde eine Ansicht über eine temporäre Tabelle empfehlen) oder Sie werden am Ende mit einer hässlichen Fall spezifischen Aussage, die sein wird ein Alptraum, der im Laufe der Zeit gemeistert wird.

+0

Können Sie tatsächlich Ansichten über temporäre Tabellen erstellen? Ich stimme zu, dass es wahrscheinlich ist, dass temporäre Tabellen der sauberste Weg sind. –

+0

Ich meine eine Ansicht statt einer temporären Tabelle ... Eine Sicht auf eine temporäre Tabelle wäre ziemlich sinnlos, Sie könnten auch die temporäre Tabelle gleich beim ersten Mal erstellen. – cjk