Steg för steg förklaring:
Först beställer du tabellen efter namn och tidsstämpel och initierar tre användare -definierade variabler .
SELECT s.* FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp
Som du kan se kan vi använda en underfråga för det. ORDER BY
är viktigt, eftersom det inte finns någon ordning i en relationsdatabas, såvida du inte anger det.
Nu utvärderar MySQL SELECT
klausul i den angivna ordningen, ändra därför inte ordningen här.
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
När du kör den här satsen kan du se att när vi helt enkelt väljer variablerna håller de värdet på föregående rad eller NULL när det är den första raden som lästes. Därefter tilldelas värdet på den aktuella raden till variablerna. Så vi kan nu jämföra den nuvarande raden med föregående rad. Om något förändrades ökar vi helt enkelt den tredje variabeln, som är ett tal för varje "grupp" som vi bygger.
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
Så vi ökade @group_number
när något ändrades och tilldelade variabeln till sig själv om inte, så att den inte ändras.
Nu kan vi helt enkelt använda den här frågan som underfråga och göra en enkel gruppering.
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
- se att det fungerar i denna sqlfiddle