Descobrindo se datas, horas, timestamps se cruzam no SQL (OVERLAPS)
Imagine que você tem uma tabela SQL com calendário de compromissos. Você gostaria de escrever nela um compromisso dia 10/01/2018 das 12:00 às 13:00. Mas espere, antes de inserir esse compromisso na tabela, você quer descobrir se há algum outro compromisso acontecendo das 12:00 às 13:00 do mesmo dia.
Descobri recentemente uma função/operação muito legal padrão do SQL chamada OVERLAPS que ajuda muito nisso.
Ela serve pra comparar se dois eventos de tempo (intervalos de tempo, que tenham um início e um fim) "se encostam", "se sobrepõem", "se interseccionam", "tem intersecção", "conflitam em algum horário".
A função precisa de 4 valores:
- "Início 1","Fim 1"
- "Início 2","Fim 2"
Aqui pergunto se as datas 01/01/2018 00:00 até 02/01/2018 00:00 tem intersecção com 01/01/2018 00:00 até 03/01/2018 00:00:
[code language="sql"] SELECT ('2018-01-01 00:00:00'::TIMESTAMP, '2018-01-02 00:00:00'::TIMESTAMP) OVERLAPS ('2018-01-01 00:00:00'::TIMESTAMP, '2018-01-03 00:00:00'::TIMESTAMP);
--Retorna TRUE, ou seja, os 2 eventos "se encostam" [/code]
Como há intersecção entre os valores, ele retornou VERDADEIRO.
Veja o que acontece neste exemplo:
[code language="sql"] SELECT ('2018-01-01 00:00:00'::TIMESTAMP, '2018-01-02 00:00:00'::TIMESTAMP) OVERLAPS ('2018-01-02 00:00:00'::TIMESTAMP, '2018-01-03 00:00:00'::TIMESTAMP); --Retorna FALSE, ou seja, os 2 eventos não "se encostam" [/code]
Retorna FALSO, porque não há intersecção.
Isso acontece porque os valores de Início são intervalo fechado, e os valores de Fim são intervalo aberto.
Outra forma de explicar é:
- Início é >=
- Fim é <
Paralelo com os tipos RANGE do PostgreSQL
O OVERLAP é praticamente igual ao operador && do tipo TSRANGE, quando ambos os TSRANGEs forem construídos com '[)' (valor padrão, caso esse atributo não seja informado no construtor).
Referências
https://www.postgresql.org/docs/current/static/functions-datetime.html
https://dba.stackexchange.com/questions/59074/2-b-tree-indices-or-1-gist-index-on-tsrange-which-will-perform-better