Creazione calendario in SQL
23-09-2024
Con prefestivi e festivi
TSQL
23-09-2024
Con prefestivi e festivi
Primo creo una funzione che calcola il giorno della Pasqua
CREATE FUNCTION [DBO].[CALCOLAGIORNOPASQUA](@ANNO AS SMALLINT)
RETURNS DATETIME AS
BEGIN
DECLARE @MESE AS VARCHAR(2)
DECLARE @GIORNO AS VARCHAR(2)
DECLARE @ANNOS AS VARCHAR(4)
DECLARE @A AS SMALLINT, @B AS SMALLINT, @C AS SMALLINT, @D AS SMALLINT, @E AS SMALLINT, @M AS SMALLINT, @N AS SMALLINT
DECLARE @DA AS SMALLINT, @MO AS SMALLINT
SET @M = 24
SET @N = 5
SET @A = @ANNO % 19
SET @B = @ANNO % 4
SET @C = @ANNO % 7
SET @D = ((19 * @A) + @M) % 30
SET @E = ((2 * @B) + (4 * @C) + (6 * @D) + @N) % 7
IF (@D + @E < 10)
BEGIN
SET @DA = @D + @E + 22
SET @MO = 3
END
ELSE
BEGIN
SET @DA = @D + @E - 9
SET @MO = 4
END
IF (@DA = 26 AND @MO = 4)
BEGIN
SET @DA = 19
SET @MO = 4
END
ELSE
BEGIN
IF (@DA = 25 AND @MO = 4 AND @D = 28 AND @E = 6 AND @A > 10)
BEGIN
SET @DA = 18
SET @MO = 4
END
END
SET @ANNOS = LTRIM(RTRIM(STR(@ANNO)))
SET @MESE = RIGHT('00' + LTRIM(RTRIM(STR(@MO))),2)
SET @GIORNO = RIGHT('00' + LTRIM(RTRIM(STR(@DA))),2)
RETURN CONVERT(DATETIME,@ANNOS+@MESE+@GIORNO)
END
Estraggo la tabella con indicati festivi e prefestivi
-- VARIABILI
DECLARE @ANNO INT = 2025
DECLARE @PREFESTIVO VARCHAR(20) = 'Prefestivo'
DECLARE @FESTIVO VARCHAR(20) = 'Festivo'
DECLARE @NORMALE VARCHAR(20) = 'Normale'
SET DATEFIRST 1
-- FINE VARIABILI
DECLARE @DATA_INIZIO DATE
DECLARE @DATA_FINE DATE
DECLARE @CALENDARIO TABLE (
ROWID INT NOT NULL PRIMARY KEY IDENTITY(1,1)
, [DATA] DATE
, GIORNO_SETTIMANA VARCHAR(20)
, TIPO VARCHAR(20)
, N_SETTIMANA INT
, GIORNO INT
, MESE INT
, ANNO INT
, PROCESSATO INT DEFAULT 0
)
SELECT
@DATA_INIZIO = CONVERT(VARCHAR(4), @ANNO) + '-01-01',
@DATA_FINE = CONVERT(VARCHAR(4), @ANNO) + '-12-31'
DECLARE @DATE INT
WITH CTE_CALENDARIO
AS
(
SELECT CAST(@DATA_INIZIO AS DATE) AS [DATE]
UNION ALL
SELECT DATEADD(DD, 1, [DATE])
FROM CTE_CALENDARIO
WHERE DATEADD(DD, 1, [DATE]) <= @DATA_FINE
)
INSERT INTO @CALENDARIO ([DATA], GIORNO_SETTIMANA, TIPO, N_SETTIMANA, GIORNO, MESE, ANNO)
SELECT
[DATE]
,(
SELECT CASE DATEPART(WEEKDAY,[DATE])
WHEN 1 THEN 'Lunedì'
WHEN 2 THEN 'Martedì'
WHEN 3 THEN 'Mercoledì'
WHEN 4 THEN 'Giovedì'
WHEN 5 THEN 'Venerdì'
WHEN 6 THEN 'Sabato'
WHEN 7 THEN 'Domenica'
END
)
, @NORMALE
,DATEPART(WEEK, [DATE])
,DATEPART(DAY,[DATE])
,DATEPART(MONTH, [DATE])
,DATEPART(YEAR,[DATE])
FROM CTE_CALENDARIO
OPTION (MAXRECURSION 0);
UPDATE @CALENDARIO
SET TIPO = @FESTIVO
WHERE GIORNO_SETTIMANA = 'Domenica'
UPDATE @CALENDARIO
SET TIPO = @PREFESTIVO
WHERE GIORNO_SETTIMANA = 'Sabato'
UPDATE @CALENDARIO
SET TIPO = @FESTIVO
WHERE [DATA] = CONVERT(VARCHAR(4), @ANNO) + '-01-01'
UPDATE @CALENDARIO
SET TIPO = @FESTIVO
WHERE [DATA] = CONVERT(VARCHAR(4), @ANNO) + '-01-06'
UPDATE @CALENDARIO
SET TIPO = @FESTIVO
WHERE [DATA] = CONVERT(VARCHAR(4), @ANNO) + '-04-25'
UPDATE @CALENDARIO
SET TIPO = @FESTIVO
WHERE [DATA] = DATEADD(DAY, 1, dbo.CALCOLAGIORNOPASQUA(@ANNO)) -- PASQUETTA
UPDATE @CALENDARIO
SET TIPO = @FESTIVO
WHERE [DATA] = CONVERT(VARCHAR(4), @ANNO) + '-05-01'
UPDATE @CALENDARIO
SET TIPO = @FESTIVO
WHERE [DATA] = CONVERT(VARCHAR(4), @ANNO) + '-06-02'
UPDATE @CALENDARIO
SET TIPO = @FESTIVO
WHERE [DATA] = CONVERT(VARCHAR(4), @ANNO) + '-08-15'
UPDATE @CALENDARIO
SET TIPO = @FESTIVO
WHERE [DATA] = CONVERT(VARCHAR(4), @ANNO) + '-11-01'
UPDATE @CALENDARIO
SET TIPO = @FESTIVO
WHERE [DATA] = CONVERT(VARCHAR(4), @ANNO) + '-12-08'
UPDATE @CALENDARIO
SET TIPO = @PREFESTIVO
WHERE [DATA] = CONVERT(VARCHAR(4), @ANNO) + '-12-24'
UPDATE @CALENDARIO
SET TIPO = @PREFESTIVO
WHERE [DATA] = CONVERT(VARCHAR(4), @ANNO) + '-12-25'
UPDATE @CALENDARIO
SET TIPO = @FESTIVO
WHERE [DATA] = CONVERT(VARCHAR(4), @ANNO) + '-12-26'
UPDATE @CALENDARIO
SET TIPO = @PREFESTIVO
WHERE [DATA] = CONVERT(VARCHAR(4), @ANNO) + '-12-31'
DECLARE @ROWID INT
WHILE (SELECT COUNT(*) FROM @CALENDARIO WHERE PROCESSATO = 0) > 0
BEGIN
DECLARE @TIPO_OGGI VARCHAR(20) = ''
DECLARE @TIPO_PREC VARCHAR(20) = ''
DECLARE @TIPO_SUCC VARCHAR(20) = ''
DECLARE @GIORNO_OGGI VARCHAR(20) = ''
DECLARE @GIORNO_PREC VARCHAR(20) = ''
DECLARE @GIORNO_SUCC VARCHAR(20) = ''
SELECT TOP 1 @ROWID = ROWID, @TIPO_OGGI = TIPO, @GIORNO_OGGI = GIORNO_SETTIMANA FROM @CALENDARIO WHERE PROCESSATO = 0
IF @ROWID > 1
BEGIN
SELECT TOP 1 @TIPO_PREC = TIPO, @GIORNO_PREC = GIORNO_SETTIMANA FROM @CALENDARIO WHERE ROWID = @ROWID - 1
IF @TIPO_OGGI = @FESTIVO AND @TIPO_PREC <> @PREFESTIVO
BEGIN
UPDATE @CALENDARIO SET TIPO = @PREFESTIVO WHERE ROWID = @ROWID - 1
END
END
IF (@ROWID + 1) < (SELECT MAX(ROWID) FROM @CALENDARIO)
BEGIN
SELECT TOP 1 @TIPO_SUCC = TIPO, @GIORNO_SUCC = GIORNO_SETTIMANA FROM @CALENDARIO WHERE ROWID = @ROWID + 1
IF @TIPO_OGGI = @FESTIVO AND @TIPO_SUCC = @FESTIVO
BEGIN
UPDATE @CALENDARIO SET TIPO = @PREFESTIVO WHERE ROWID = @ROWID
END
END
UPDATE @CALENDARIO SET PROCESSATO = 1 WHERE ROWID = @ROWID
END;
SELECT * FROM @CALENDARIO