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:

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"

Como há intersecção entre os valores, ele retornou VERDADEIRO.

Veja o que acontece neste exemplo:

 
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" 

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

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *