Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Daten in einer neuen Tabelle zusammenfassen

Schritt-für-Schritt-Erklärung:

Zuerst ordnet man die Tabelle nach Namen und Zeitstempel und initialisiert drei Benutzer -definierte Variablen .

SELECT s.* FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp

Wie Sie sehen können, können wir dafür eine Unterabfrage verwenden. Der ORDER BY ist wichtig, da es in einer relationalen Datenbank keine Reihenfolge gibt, es sei denn, Sie geben sie an.

Nun wertet MySQL den SELECT aus -Klausel in der angegebenen Reihenfolge, ändern Sie daher die Reihenfolge hier nicht.

SELECT 
s.*,
@prevName,
@prevStatus,
@prevName := s.name,
@prevStatus := s.status
FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp

Wenn Sie diese Anweisung ausführen, können Sie sehen, dass, wenn wir die Variablen einfach auswählen, sie den Wert der vorherigen Zeile oder NULL enthalten, wenn es die erste Zeile ist, die gelesen wurde. Dann wird den Variablen der Wert der aktuellen Zeile zugewiesen. So können wir jetzt die aktuelle Zeile mit der vorherigen Zeile vergleichen. Wenn sich etwas geändert hat, erhöhen wir einfach die dritte Variable, die eine Zahl für jede "Gruppe" ist, die wir erstellen.

SELECT 
s.*,
@group_number := IF(@prevName != s.name OR @prevStatus != s.status, @group_number + 1, @group_number) AS group_number,
@prevName := s.name,
@prevStatus := s.status
FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp

Also haben wir @group_number erhöht wenn sich etwas geändert hat und die Variable sich selbst zugewiesen hat, wenn nicht, damit sie sich nicht ändert.

Jetzt können wir diese Abfrage einfach als Unterabfrage verwenden und eine einfache Gruppierung vornehmen.

SELECT 
group_number AS id, 
name, 
status, 
MIN(error) AS error, 
MIN(timestamp) AS firstEntry,
MAX(timestamp) AS lastEntry,
COUNT(*) AS entries
FROM (
    SELECT 
    s.*,
    @group_number := IF(@prevName != s.name OR @prevStatus != s.status, @group_number + 1, @group_number) AS group_number,
    @prevName := s.name,
    @prevStatus := s.status
    FROM status_table s
    , (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
    ORDER BY name, timestamp
) sq
GROUP BY 
group_number, 
name, 
status
  • Sehen Sie, wie es in diesem sqlfiddle funktioniert