Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Resumir dados em uma nova tabela


Explicação passo a passo:

Primeiro você ordena a tabela por nome e timestamp e inicializa três user -variáveis ​​definidas .
SELECT s.* FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp

Como você pode ver, podemos usar uma subconsulta para isso. O ORDER BY é importante, porque não há ordem em um banco de dados relacional, a menos que você a especifique.

Agora, o MySQL avalia o SELECT cláusula na ordem especificada, portanto, não altere a ordem aqui.
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

Ao executar esta instrução, você pode ver que, quando simplesmente selecionamos as variáveis, elas mantêm o valor da linha anterior ou NULL quando é a primeira linha, que foi lida. Em seguida, o valor da linha atual é atribuído às variáveis. Assim, podemos comparar agora a linha atual com a linha anterior. Se algo mudou, simplesmente incrementamos a terceira variável, que é um número para cada "grupo" que estamos construindo.
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

Então incrementamos o @group_number quando algo mudou e atribuiu a variável a si mesma, se não, para que não mude.

Agora podemos simplesmente usar essa consulta como subconsulta e fazer um agrupamento simples.
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