Verificando conflitos de horário com T-SQL em uma tabela de Compromissos/Tarefas/Agenda

 Vamos criar um banco de dados chamado DbCompromissos e nele iremos criar uma tabela para armazenar os compromissos que temos durante o dia.

Nessa tabela teremos a data e hora inicial do compromisso, o tempo em minutos que esse compromisso durará e uma coluna calculada com a data de termino do compromisso.

A coluna calculada será a soma data hora inicial do compromisso com o tempo em minutos 

-- CRIAR O BANCO DE DADOS
CREATE DATABASE DbCompromissos
GO

-- SELECIONAR O BANCO DE DADOS
USE DbCompromissos
GO

 -- CRIAR A TABELA DE COMPROMISSOS
CREATE
TABLE Compromissos
(
    Id int primary key identity(1,1) not null,
    titulo varchar(100) not null,
    dataHoraInicial datetime not null,
    tempoEmMinutos int not null,
    dataHoraFinal AS DATEADD(MINUTE, tempoEmMinutos, dataHoraInicial )
)

 -- CADASTRAR O PRIMEIRO COMPROMISSO
INSERT INTO Compromissos (titulo, dataHoraInicial, tempoEmMinutos)
VALUES ('Apresentação de Sistema', '03/03/2021 08:00', 45)

 -- CADASTRAR O SEGUNDO COMPROMISSO
INSERT INTO Compromissos (titulo, dataHoraInicial, tempoEmMinutos)
VALUES ('Reunião Diaria', '03/03/2021 09:10', 15)

 -- CADASTRAR O TERCEIRO COMPROMISSO
INSERT INTO Compromissos (titulo, dataHoraInicial, tempoEmMinutos)
VALUES ('Apresentação de Proposta para Cliente', '03/03/2021 10:00', 15)


Após isso teremos um banco de dados e os seguintes registros na tabela Compromissos


select * from Compromissos 



Agora vamos validar a inclusão de uma tarefa com a seguinte condição (desconsiderando o minuto de início e fim de uma tarefa já existente) sendo assim se a tarefa começar as 08:45 e já existir uma tarefa na base de dadas terminando as 08:45, esse primeiro exemplo não dará conflito de horários.


DECLARE @dataHoraInicialNovaTarefa AS Datetime = '03/03/2021 08:45'
DECLARE @tempoNovaTarefa AS int = 25 

DECLARE @dataHoraFinalNovaTarefa AS DATETIME = DATEADD(MINUTE, @tempoNovaTarefa, @dataHoraInicialNovaTarefa) 

SELECT    @dataHoraInicialNovaTarefa DataInicioNovaTarefa,
          @dataHoraFinalNovaTarefa DataFimNovaTarefa 


SELECT
COUNT(*) QtdConflitos FROM Compromissos
WHERE
    -- COMEÇA DENTRO DO PERIODO EXISTENTE 
    (@dataHoraInicialNovaTarefa >= dataHoraInicial AND @dataHoraInicialNovaTarefa < dataHoraFinal)     
    
    OR
    
    -- TERMINA DENTRO DO PERIODO EXISTENTE
    (@dataHoraFinalNovaTarefa > dataHoraInicial AND @dataHoraFinalNovaTarefa <= dataHoraFinal
    

    OR
    
    -- ENGLOBA UM PERIODO EXISTENTE 
    (@dataHoraInicialNovaTarefa <= dataHoraInicial AND @dataHoraFinalNovaTarefa >= dataHoraFinal)


 O resultado que teremos nesse caso será 


Agora ao alterarmos o SELECT para verificar também os minutos iniciais e finais de tarefas já existentes então teremos dois conflitos 

DECLARE @dataHoraInicialNovaTarefa AS Datetime = '03/03/2021 08:45'
DECLARE @tempoNovaTarefa AS int = 25 

DECLARE @dataHoraFinalNovaTarefa AS DATETIME = DATEADD(MINUTE, @tempoNovaTarefa, @dataHoraInicialNovaTarefa) 

SELECT    @dataHoraInicialNovaTarefa DataInicioNovaTarefa,
          @dataHoraFinalNovaTarefa DataFimNovaTarefa 


SELECT
 COUNT(*) QtdConflitos FROM Compromissos
WHERE
    -- COMEÇA DENTRO DO PERIODO EXISTENTE 
    (@dataHoraInicialNovaTarefa >= dataHoraInicial AND @dataHoraInicialNovaTarefa <= dataHoraFinal)     
    
    OR
    
    -- TERMINA DENTRO DO PERIODO EXISTENTE
    (@dataHoraFinalNovaTarefa >= dataHoraInicial AND @dataHoraFinalNovaTarefa <= dataHoraFinal
    

    OR
    
    -- ENGLOBA UM PERIODO EXISTENTE 
    (@dataHoraInicialNovaTarefa <= dataHoraInicial AND @dataHoraFinalNovaTarefa >= dataHoraFinal)


O Resultado será 



Comentários