Escolar Documentos
Profissional Documentos
Cultura Documentos
Server
29 de julho de 2015 body_of_rays
Ol Pessoal,
Bom dia.
Neste post irei mostrar como realizar diversos clculos com dias teis no
SQL Server, criando uma tabela com todas as informaes j calculadas
e restando apenas realizar alguns SELECTs simples para obter essas
informaes.
1
2 CREATE FUNCTION [dbo].[fncDia_Util_Anterior] ( @Data_Dia DATETIME )
3 RETURNS DATETIME
4 AS
5 BEGIN
6
WHILE (1 = 1)
7
BEGIN
8
9
SET @Data_Dia = @Data_Dia - (CASE DATEPART(WEEKDAY, @Data_Dia) WHEN 1 THE
10
11
IF EXISTS ( SELECT TOP 1 Nr_Dia FROM dbo.Feriado WITH ( NOLOCK ) WHERE Nr
12
( Nr_Ano = 0 OR Nr_Ano = YEAR(@Data_Dia) ) )
13
SET @Data_Dia = @Data_Dia - 1
14
ELSE
15
BREAK
16
17
END
18
19
RETURN CAST(FLOOR(CAST(@Data_Dia AS FLOAT)) AS DATETIME)
20
END
fncProximo_Dia_Util
1
2
3
4
5
6
WHILE (1 = 1)
7
BEGIN
8
9
SET @Data_Dia = @Data_Dia + (CASE DATEPART(WEEKDAY, @Data_Dia) WHEN 1 THE
10
11
IF EXISTS ( SELECT TOP 1 Nr_Dia FROM dbo.Feriado WITH ( NOLOCK ) WHERE Nr
12
( Nr_Ano = 0 OR Nr_Ano = YEAR(@Data_Dia) ) )
13
SET @Data_Dia = @Data_Dia + 1
14
ELSE
15
BREAK
16
END
17
18
RETURN CAST(FLOOR(CAST(@Data_Dia AS FLOAT)) AS DATETIME)
19
END
fncDia_Util
1
2 CREATE FUNCTION [dbo].[fncDia_Util] ( @Data_Dia DATETIME )
3 RETURNS BIT
4 AS
5 BEGIN
6
DECLARE @retorno BIT
7
8
IF ( DATEPART(WEEKDAY, @Data_Dia) IN ( 1, 7 ) )
9
SET @retorno = 0
10
ELSE
11
BEGIN
12
13
IF EXISTS ( SELECT TOP 1 Nr_Dia FROM dbo.Feriado WITH ( NOLOCK ) WHERE Nr
14 ( Nr_Ano = 0 OR Nr_Ano = YEAR(@Data_Dia) ) )
15
SET @retorno = 0
16
ELSE
17
SET @retorno = 1
18
19
END
20
21
RETURN @retorno
22
END
16
Nr_Semana INT,
17
Nr_Semana_Mes INT,
18
Nr_Dia_Ano INT,
19
Qt_Dias_Uteis_Mes INT NULL,
20
Qt_Dias_Uteis_Ano INT NULL
21 )
22
23 DECLARE @Dt_Inicial DATETIME = '19900101', @Dt_Final DATETIME = '20991231'
24
25 WHILE (@Dt_Inicial <= @Dt_Final)
26 BEGIN
27
INSERT INTO dbo.Dia_Util
28
SELECT
29
@Dt_Inicial AS Dt_Referencia,
30
DATEPART(DAY, @Dt_Inicial) AS Nr_Dia,
31
DATEPART(MONTH, @Dt_Inicial) AS Nr_Mes,
32
DATEPART(YEAR, @Dt_Inicial) AS Nr_Ano,
33
dbo.fncDia_Util_Anterior(DATEADD(DAY, -1, @Dt_Inicial)) AS Dt_Dia_Util_Anteri
34
dbo.fncProximo_Dia_Util(DATEADD(DAY, 1, @Dt_Inicial)) AS Dt_Proximo_Dia_Util,
35
dbo.fncDia_Util(@Dt_Inicial) AS Fl_Dia_Util,
36
(CASE WHEN DATEPART(WEEKDAY, @Dt_Inicial) = 1 OR EXISTS(SELECT TOP 1 Nr_D
37
MONTH(
@Dt_Inicial
) AND Tp_Feriado = '1' AND (Nr_Ano = 0 OR Nr_Ano = YEAR(@Dt_Inici
38
(CASE
WHEN
EXISTS(SELECT TOP 1 Nr_Dia FROM dbo.Feriado WITH(NOLOCK) WHER
39
40 = 0 OR Nr_Ano = YEAR(@Dt_Inicial))) THEN 1 ELSE 0 END) AS Fl_Feriado,
DATEPART(WEEKDAY, @Dt_Inicial) AS Nr_Dia_Semana,
41
DATENAME(WEEKDAY, @Dt_Inicial) AS Ds_Dia_Semana,
42
DATEPART(WEEK, @Dt_Inicial) AS Nr_Semana,
43
DATEPART(WEEK, @Dt_Inicial) - DATEPART(WEEK, @Dt_Inicial - DATEPART(DAY, @Dt
44
DATEPART(DAYOFYEAR, @Dt_Inicial) AS Nr_Dia_Ano,
45
NULL AS Qt_Dias_Uteis_Mes,
46
NULL AS Qt_Dias_Uteis_Ano
47
48
49
SET @Dt_Inicial = DATEADD(DAY, 1, @Dt_Inicial)
50
51
52 END
53
54
55 -- POPULA A QUANTIDADE DE DIAS TEIS AT A DATA
56 DECLARE @Qt_Dias_Uteis_Mes INT, @Qt_Dias_Uteis_Ano INT
57
58 SET @Dt_Inicial = '19900101'
59
60 WHILE (@Dt_Inicial <= @Dt_Final)
61 BEGIN
62
63
SET @Qt_Dias_Uteis_Mes = (SELECT COUNT(*) FROM dbo.Dia_Util WITH(NOLOCK) WHER
64
Nr_Mes = MONTH(@Dt_Inicial))
65
SET @Qt_Dias_Uteis_Ano = (SELECT COUNT(*) FROM dbo.Dia_Util WITH(NOLOCK) WHER
66
67
68
UPDATE
69
A
70
SET
71
Qt_Dias_Uteis_Mes = @Qt_Dias_Uteis_Mes,
72
Qt_Dias_Uteis_Ano = @Qt_Dias_Uteis_Ano
73
FROM
74
dbo.Dia_Util A
75
WHERE
76
Dt_Referencia = @Dt_Inicial
77
78
SET @Dt_Inicial = DATEADD(DAY, 1, @Dt_Inicial)
79
80 END
81
CREATE CLUSTERED INDEX Idx01 ON dbo.Dia_Util(Dt_Referencia)
isso a, pessoal!
At o prximo post!