2016-07-22 35 views
0

Hier Verschmelzung ist der Code, den ich laufe Server-Logs auf MySQL-Datenbank zu analysieren:Kombinieren und Daten auf verschiedene MySQL-Tabellen mit den gleichen Spalten in eindeutige Zeilen und ausgeführte Abfrage, um es

SELECT YEAR(datetime), MONTH(datetime), MIN(DATE(datetime)), MAX(DATE(datetime)), COUNT(DISTINCT (ip)), COUNT(ip), (COUNT(ip)/COUNT(DISTINCT (ip))) AS Ratio 
FROM `server_log_1` 
WHERE `state` LIKE 'action' 
AND `user_id` LIKE '9' 
GROUP BY MONTH(datetime) 
UNION 
SELECT YEAR(datetime), MONTH(datetime), MIN(DATE(datetime)), MAX(DATE(datetime)), COUNT(DISTINCT (ip)), COUNT(ip), (COUNT(ip)/COUNT(DISTINCT (ip))) AS Ratio 
FROM `server_log_2` 
WHERE `state` LIKE 'action' 
AND `user_id` LIKE '9' 
GROUP BY MONTH(datetime) 
UNION 
SELECT YEAR(datetime), MONTH(datetime), MIN(DATE(datetime)), MAX(DATE(datetime)), COUNT(DISTINCT (ip)), COUNT(ip), (COUNT(ip)/COUNT(DISTINCT (ip))) AS Ratio 
FROM `server_log_3` 
WHERE `state` LIKE 'action' 
AND `user_id` LIKE '9' 
GROUP BY MONTH(datetime) 

Das gibt mir das Ergebnis :

YEAR(datetime) MONTH(datetime) MIN(DATE(datetime)) MAX(DATE(datetime)) COUNT(DISTINCT (ip)) COUNT(ip) Ratio 
2015    12    2015-12-14    2015-12-30    16    20    1.2500 
2016    1    2016-01-05    2016-01-27    15    20    1.3333 
2016    2    2016-02-02    2016-02-29    27    36    1.3333 
2016    3    2016-03-04    2016-03-29    24    32    1.3333 
2016    4    2016-04-01    2016-04-08    5    8    1.6000 
2016    4    2016-04-09    2016-04-29    19    27    1.4211 
2016    5    2016-05-02    2016-05-28    21    31    1.4762 
2016    6    2016-06-01    2016-06-30    28    34    1.2143 
2016    7    2016-07-01    2016-07-20    14    16    1.1429 
2016    7    2016-07-21    2016-07-21    1    1    1.0000 

diese jede Datenbank präzise Ergebnisse für die sind aber Sie sehen, wenn ein Monat in zwei verschiedenen Datenbanken aufgeteilt wird, (wie 2016-4 und 2016-7) dies bewirkt, dass zwei unterschiedliche Reihen für diesen Monat generiert.

Ich möchte, dass diese Zeilen als eine einzelne Zeile generiert werden, die die Summe der Werte des entsprechenden Monats hat. (nur eine Zeile pro Monat)

Auch die Abfrage möglichst vereinfachen.

Und ich werde in Schwierigkeiten nach 2016-12 sein, wo die Gruppierung nach Monat Daten von 2015-12 und 2016-12 zusammenführen wird. Wie kann ich dieses Problem auch vermeiden?

Können Sie bitte die richtige SQL-Anweisung schreiben?

+0

teilen Sie einfach das gewünschte Ergebnis .. mehr Details .. Bild wenn möglich –

Antwort

1

Wie wäre es die union all vor dem group by tun:

SELECT YEAR(datetime), MONTH(datetime), MIN(DATE(datetime)), MAX(DATE(datetime)), COUNT(DISTINCT (ip)), COUNT(ip), (COUNT(ip)/COUNT(DISTINCT (ip))) AS Ratio 
FROM (
    (SELECT datetime, ip FROM server_log_1 WHERE state = 'action' AND user_id = 9) UNION ALL 
    (SELECT datetime, ip FROM server_log_2 WHERE state = 'action' AND user_id = 9) UNION ALL 
    (SELECT datetime, ip FROM server_log_3 WHERE state = 'action' AND user_id = 9) 
) AS table_all 
GROUP BY YEAR(datetime), MONTH(datetime); 

In Bezug auf Leistung, möchten Sie für jede Tabelle einen Index für state, user_id (und vielleicht datetime und ip Zugabe).

+0

Haben Sie auch eine Lösung, um alle server_log_4, _5, _6 Tabellen in Zukunft gebildet, automatisch in der Abfrage enthalten? – Tarik

+0

@Tarik. . . Ich würde empfehlen, dass Sie die Tabellenpartitionierung untersuchen, aber das ist bei dieser Frage nicht möglich. –