Calculando dias úteis com SQL Server

Calculando dias úteis com SQL Server

Neste artigo você vai aprender como calcular dias úteis utilizando o SQL Server.

O cálculo de dias úteis é muito importante e tem várias aplicações, como por exemplo o cálculo de prazos de entrega e de pagamentos.

Vamos considerar como dia útil uma data que seja entre segunda a sexta, e que não caia em algum feriado.

Para servir de referência, vamos primeiro criar uma tabela com os feriados nacionais de 2020.

CREATE TABLE [dbo].[feriados](

[id] [int] IDENTITY(1,1) NOT NULL,

[data] [date] NULL,

[descricao] [varchar](50) NULL,

 CONSTRAINT [PK_feriados] PRIMARY KEY CLUSTERED 

(

[id] ASC

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

) ON [PRIMARY]

 

Depois de criar a tabela, vamos inserir os registros com os feriados de 2020.

 

INSERT INTO feriados (data, descricao) VALUES ('2020-01-01', 'Confraternização Universal')

INSERT INTO feriados (data, descricao) VALUES ('2020-04-10', 'Paixão de Cristo')

INSERT INTO feriados (data, descricao) VALUES ('2020-04-21', 'Tiradentes')

INSERT INTO feriados (data, descricao) VALUES ('2020-05-01', 'Dia Mundial do Trabalho')

INSERT INTO feriados (data, descricao) VALUES ('2020-09-07', 'Independência do Brasil')

INSERT INTO feriados (data, descricao) VALUES ('2020-10-12', 'Nossa Senhora Aparecida')

INSERT INTO feriados (data, descricao) VALUES ('2020-11-02', 'Finados')

INSERT INTO feriados (data, descricao) VALUES ('2020-11-15', 'Proclamação da República')

INSERT INTO feriados (data, descricao) VALUES ('2020-12-25', 'Natal')

 

Para conferir, basta fazer:

 

SELECT * from feriados

 

Com a nossa tabela criada, vamos criar uma funçao para facilitar a geração de datas com base numa quantidade de dias úteis a ser informada pelo usuário. Antes de criar a função,  vamos entrar em detalhes de como ela vai funcionar:

 

1 - A função vai receber dois parâmetros, a data inicial e a quantidade de dias úteis a ser calculada.

2 - Será feito um loop de acordo com a quantidade de dias solicitados

3 - A data inicial será incrementada em 1 dia antes e durante a execução do loop

4 - Para cada nova data, será verificado se a nova data está no intervalo de dia da semana válido, e se a data não está em nossa tabela de feriados

5 - Ao concluir o loop, será retornada a nova data.

 

Existem três pontos que vamos dar uma olhada antes de criar a função. O primeiro é: Como saber o dia da semana de acordo com a data?

Para isso, se utiliza a funçao DATEPART, ela recebe dois parâmetros, o tipo de retorno e a data a ser analisada. O tipo de retorno que será utilizado é o WEEKDAY.

select DATEPART(WEEKDAY, '2020-02-29')

O retorno desta data é 7 (sábado). O retorno vai ser um número de 1 a 7. Por padrão, a semana começa no domingo (1) e termina no sábado (7).

O outro ponto que vamos ver é como adicionar dias a uma data. Para isso, se utilizada a função DATEADD, ela recebe 3 parâmetros, o primeiro é a referência (dias, mês, ano, etc...), o segundo é um número que representa a quantidade que vai ser adicionada, e por último, a data.  Se você informar a data de hoje e quiser saber a data de amanhã,  basta fazer a seguinte consulta:

SELECT DATEADD(DAY, 1, GETDATE())

Por último, para fazer o loop de acordo com a quantidade de dias solicitados, será utilizada uma estrutura de repetição chamada "While", que vai executar certas instruções enquanto uma variável de referência for válida.

DECLARA @DIAS_UTEIS INT  = 30

DECLARE @CONTADOR INT  = 0

WHILE @CONTADOR < @DIAS_UTEIS 

    BEGIN 

//Instrucoes que vamos executar

    SET @CONTADOR += 1; //Incrementar o contador

    END 

No exemplo acima ele vai executar as instrucoes dentro do While enquanto a variável "contador" for menor que 30.

Agora vamos criar a nossa função. Ela vai chamar "adicionar_dias_uteis", e vai receber dois parâmetros, uma data e uma quantidade de dias úteis. Seu retorno vai ser uma data.

CREATE FUNCTION adicionar_dias_uteis (

  @DATA      DATE,

  @DIAS_UTEIS     INT   

) RETURNS DATE     

BEGIN         

 

       IF @DATA IS NULL

         BEGIN       

           SET @DATA = GETDATE();

         END

 

       DECLARE @DIAS  INT  = 0

       DECLARE @CONTADOR      INT  = 0

       DECLARE @NOVA_DATA DATE = DATEADD(DAY, 1, @DATA)                                         

 

       WHILE @CONTADOR < @DIAS_UTEIS 

        BEGIN 

          IF DATEPART(WEEKDAY, @NOVA_DATA) NOT IN (7,1) AND @NOVA_DATA NOT IN ( SELECT data FROM feriados ) 

            SET @CONTADOR += 1;

            SELECT @NOVA_DATA = DATEADD(DAY, 1, @NOVA_DATA), @DIAS += 1;

        END 

 

        RETURN DATEADD(DAY, @DIAS, @DATA);

  END 

GO

 

Chegou a hora de testar. Como exemplo, vamos calcular 90 dias úteis a partir de 10/03/2020.

SELECT dbo.adicionar_dias_uteis('2020-03-10', 90)

O resultado será

2020-07-16

 

 

Outros conteudos que podem ser de seu interesse

SQL vs Pandas - Convertendo linhas em colunas
12/05/2024SQL

SQL vs Pandas - Convertendo linhas em colunas

Veja como fazer a transposição de linhas em colunas usando Pandas e SQL

Saiba mais...
Funções de manipulação de strings no SQL
14/02/2021SQL

Funções de manipulação de strings no SQL

Veja as funções de strings mais comuns utilizadas no SQL

Saiba mais...
Localizar colunas por nome ou tipo de dados no SQL
23/07/2023SQL

Localizar colunas por nome ou tipo de dados no SQL

Descubra como localizar uma coluna por nome ou tipo de dados em qualquer tabela de seu banco de dados

Saiba mais...

Conteúdo sobre banco de dados sem complicação!


Warning: Cannot modify header information - headers already sent by (output started at /home/storage/f/7d/a9/dbins/public_html/blog/post.php:101) in /home/storage/f/7d/a9/dbins/public_html/blog/ga4_track.php on line 11