Trin for trin forklaring:
Først bestiller du tabellen efter navn og tidsstempel og initialiserer tre bruger -definerede variable .
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 bruge en underforespørgsel til det. ORDER BY
er vigtigt, fordi der ikke er nogen rækkefølge i en relationsdatabase, medmindre du angiver det.
Nu evaluerer MySQL SELECT
klausul i den angivne rækkefølge, derfor skal du ikke ændre rækkefølgen her.
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 udfører denne sætning, kan du se, at når vi blot vælger variablerne, holder de værdien af den forrige række eller NULL, når det er den første række, der blev læst. Derefter tildeles værdien af den aktuelle række til variablerne. Så vi kan nu sammenligne den nuværende række med den foregående række. Hvis noget ændrede sig, øger vi simpelthen den tredje variabel, som er et tal for hver "gruppe", som vi opbygger.
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 øgede @group_number
når noget ændrede sig og tildelte variablen til sig selv, hvis ikke, så den ikke ændrer sig.
Nu kan vi simpelthen bruge denne forespørgsel som underforespørgsel og lave en simpel 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 det fungere i denne sqlfiddle