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

Como encontrar todos os intervalos de valores de timestamp por minuto entre os dois registros de timestamp no meu banco de dados sql


Com a ajuda de https://stackoverflow.com/a/45992247/7616138 para gerar uma série no MySQL eu fiddled ao redor para produzir isso:

Supondo que sua tabela seja chamada de entries , a consulta a seguir produzirá o resultado solicitado. Por favor, note que esta consulta não é muito eficiente, pois usa junções cruzadas para construir a série de minutos. Se seus intervalos forem maiores, talvez seja necessário estender as junções cruzadas.
SELECT 
    a.*, 
    DATE_ADD(DATE_SUB(a.open_date, INTERVAL SECOND(a.open_date) SECOND), INTERVAL gen_time MINUTE) AS gen_date_time
FROM 
    entries AS a
    LEFT JOIN
        (
            SELECT
                m3 * 1000 + m2 * 100 + m1 * 10 + m0 AS gen_time
            FROM
                (SELECT 0 m0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS m0,
                (SELECT 0 m1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS m1,
                (SELECT 0 m2 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS m2,
                (SELECT 0 m3 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS m3
            ORDER BY
                gen_time asc
        ) AS b ON (DATE_ADD(a.open_date, INTERVAL gen_time MINUTE) <= a.close_date)
ORDER BY
    a.id,
    gen_date_time

Explicação:

Cada linha como SELECT 0 m0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 produz os números de 0 a 9. A junção cruzada de várias dessas linhas fornece todas as combinações possíveis desses números. Usamos cada linha para produzir um dígito específico do número de minutos para adicionar a open_date (m3 * 1000 + m2 * 100 + m1 * 10 + m0 ). Esta série de minutos é unida à tabela de entradas usando apenas quantos minutos couberem no intervalo (DATE_ADD(a.open_date, INTERVAL gen_time MINUTE) <= a.close_date ). No SELECT o open_date é arredondado para o minuto (DATE_SUB(a.open_date, INTERVAL SECOND(a.open_date) SECOND) ) e o número de minutos é adicionado (DATE_ADD(..., INTERVAL gen_time MINUTE) ).

Esquema suposto e dados de amostra:
CREATE TABLE entries (
  id INT AUTO_INCREMENT PRIMARY KEY,
  open_date TIMESTAMP,
  close_date TIMESTAMP
);

INSERT INTO entries (open_date, close_date) VALUES
  ("2019-07-03 16:28:39.497", "2019-07-04 16:28:39.497"),
  ("2019-07-04 15:28:39.497", "2019-07-05 19:28:39.497");