CREATE DATABASE [Kalender] CONTAINMENT = NONE GO USE [Kalender] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Helligdag]( [HelligdagId] [int] IDENTITY(1,1) NOT NULL, [Helligdag] [nvarchar](21) NOT NULL, [AntaldageFraPåskedag] [smallint] NULL, [FastDag] [tinyint] NULL, [FastMåned] [tinyint] NULL, [FraÅr] [smallint] NOT NULL, [TilÅr] [smallint] NOT NULL, CONSTRAINT [PK_Helligdag] PRIMARY KEY CLUSTERED ( [HelligdagId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO CREATE TABLE [dbo].[Måned]( [Månedsnummer] [int] NOT NULL, [Måned] [nvarchar](9) NOT NULL, [MånedKort] [nvarchar](3) NOT NULL, [Kvartal] [nvarchar](10) NOT NULL, [Halvår] [nvarchar](9) NOT NULL, [Årstid] [nvarchar](10) NOT NULL, CONSTRAINT [PK_Månedsnummer] PRIMARY KEY CLUSTERED ( [Månedsnummer] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO CREATE TABLE [dbo].[Ugedag]( [DagIUge] [int] NOT NULL, [Ugedag] [nvarchar](7) NOT NULL, [UgedagKort] [nvarchar](3) NOT NULL, CONSTRAINT [PK_Ugedag] PRIMARY KEY CLUSTERED ( [DagIUge] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO CREATE TABLE [dbo].[Øvrigdag]( [Øvrigdag] [nvarchar](12) NOT NULL, [FastDag] [tinyint] NOT NULL, [FastMåned] [tinyint] NOT NULL, [FraÅr] [smallint] NOT NULL, [TilÅr] [smallint] NOT NULL, CONSTRAINT [PK_Øvrigdag] PRIMARY KEY CLUSTERED ( [Øvrigdag] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO CREATE TABLE [dbo].[Lukkedag]( [LukkedagId] [int] IDENTITY(1,1) NOT NULL, [Lukkedag] [nvarchar](50) NOT NULL, [AntaldageFraPåskedag] [smallint] NULL, [FastDag] [tinyint] NULL, [FastMåned] [tinyint] NULL, [FastUgenummer] [tinyint] NULL, [FraÅr] [smallint] NOT NULL, [TilÅr] [smallint] NOT NULL, CONSTRAINT [PK_Lukkedag] PRIMARY KEY CLUSTERED ( [LukkedagId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET IDENTITY_INSERT [dbo].[Helligdag] ON GO INSERT [dbo].[Helligdag] ([HelligdagId], [Helligdag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (1, N'Nytårsdag', NULL, 1, 1, 1, 9999) GO INSERT [dbo].[Helligdag] ([HelligdagId], [Helligdag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (2, N'Palmesøndag', -7, NULL, NULL, 1, 9999) GO INSERT [dbo].[Helligdag] ([HelligdagId], [Helligdag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (3, N'Skærtorsdag', -3, NULL, NULL, 1, 9999) GO INSERT [dbo].[Helligdag] ([HelligdagId], [Helligdag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (4, N'Langfredag', -2, NULL, NULL, 1, 9999) GO INSERT [dbo].[Helligdag] ([HelligdagId], [Helligdag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (5, N'Påskedag', 0, NULL, NULL, 1, 9999) GO INSERT [dbo].[Helligdag] ([HelligdagId], [Helligdag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (6, N'2. Påskedag', 1, NULL, NULL, 1, 9999) GO INSERT [dbo].[Helligdag] ([HelligdagId], [Helligdag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (7, N'Store Bededag', 26, NULL, NULL, 1, 2023) GO INSERT [dbo].[Helligdag] ([HelligdagId], [Helligdag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (8, N'Kristi Himmelfartsdag', 39, NULL, NULL, 1, 9999) GO INSERT [dbo].[Helligdag] ([HelligdagId], [Helligdag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (9, N'Pinsedag', 49, NULL, NULL, 1, 9999) GO INSERT [dbo].[Helligdag] ([HelligdagId], [Helligdag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (10, N'2. Pinsedag', 50, NULL, NULL, 1, 9999) GO INSERT [dbo].[Helligdag] ([HelligdagId], [Helligdag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (11, N'Juledag', NULL, 25, 12, 1, 9999) GO INSERT [dbo].[Helligdag] ([HelligdagId], [Helligdag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (12, N'2. Juledag', NULL, 26, 12, 1, 9999) GO SET IDENTITY_INSERT [dbo].[Helligdag] OFF GO INSERT [dbo].[Måned] ([Månedsnummer], [Måned], [MånedKort], [Kvartal], [Halvår], [Årstid]) VALUES (1, N'Januar', N'JAN', N'1. kvartal', N'1. halvår', N'Vinter') GO INSERT [dbo].[Måned] ([Månedsnummer], [Måned], [MånedKort], [Kvartal], [Halvår], [Årstid]) VALUES (2, N'Februar', N'FEB', N'1. kvartal', N'1. halvår', N'Vinter') GO INSERT [dbo].[Måned] ([Månedsnummer], [Måned], [MånedKort], [Kvartal], [Halvår], [Årstid]) VALUES (3, N'Marts', N'MAR', N'1. kvartal', N'1. halvår', N'Forår') GO INSERT [dbo].[Måned] ([Månedsnummer], [Måned], [MånedKort], [Kvartal], [Halvår], [Årstid]) VALUES (4, N'April', N'APR', N'2. kvartal', N'1. halvår', N'Forår') GO INSERT [dbo].[Måned] ([Månedsnummer], [Måned], [MånedKort], [Kvartal], [Halvår], [Årstid]) VALUES (5, N'Maj', N'MAJ', N'2. kvartal', N'1. halvår', N'Forår') GO INSERT [dbo].[Måned] ([Månedsnummer], [Måned], [MånedKort], [Kvartal], [Halvår], [Årstid]) VALUES (6, N'Juni', N'JUN', N'2. kvartal', N'1. halvår', N'Sommer') GO INSERT [dbo].[Måned] ([Månedsnummer], [Måned], [MånedKort], [Kvartal], [Halvår], [Årstid]) VALUES (7, N'Juli', N'JUL', N'3. kvartal', N'2. halvår', N'Sommer') GO INSERT [dbo].[Måned] ([Månedsnummer], [Måned], [MånedKort], [Kvartal], [Halvår], [Årstid]) VALUES (8, N'August', N'AUG', N'3. kvartal', N'2. halvår', N'Sommer') GO INSERT [dbo].[Måned] ([Månedsnummer], [Måned], [MånedKort], [Kvartal], [Halvår], [Årstid]) VALUES (9, N'September', N'SEP', N'3. kvartal', N'2. halvår', N'Efterår') GO INSERT [dbo].[Måned] ([Månedsnummer], [Måned], [MånedKort], [Kvartal], [Halvår], [Årstid]) VALUES (10, N'Oktober', N'OKT', N'4. kvartal', N'2. halvår', N'Efterår') GO INSERT [dbo].[Måned] ([Månedsnummer], [Måned], [MånedKort], [Kvartal], [Halvår], [Årstid]) VALUES (11, N'November', N'NOV', N'4. kvartal', N'2. halvår', N'Efterår') GO INSERT [dbo].[Måned] ([Månedsnummer], [Måned], [MånedKort], [Kvartal], [Halvår], [Årstid]) VALUES (12, N'December', N'DEC', N'4. kvartal', N'2. halvår', N'Vinter') GO INSERT [dbo].[Ugedag] ([DagIUge], [Ugedag], [UgedagKort]) VALUES (1, N'Mandag', N'MAN') GO INSERT [dbo].[Ugedag] ([DagIUge], [Ugedag], [UgedagKort]) VALUES (2, N'Tirsdag', N'TIR') GO INSERT [dbo].[Ugedag] ([DagIUge], [Ugedag], [UgedagKort]) VALUES (3, N'Onsdag', N'ONS') GO INSERT [dbo].[Ugedag] ([DagIUge], [Ugedag], [UgedagKort]) VALUES (4, N'Torsdag', N'TOR') GO INSERT [dbo].[Ugedag] ([DagIUge], [Ugedag], [UgedagKort]) VALUES (5, N'Fredag', N'FRE') GO INSERT [dbo].[Ugedag] ([DagIUge], [Ugedag], [UgedagKort]) VALUES (6, N'Lørdag', N'LØR') GO INSERT [dbo].[Ugedag] ([DagIUge], [Ugedag], [UgedagKort]) VALUES (7, N'Søndag', N'SØN') GO INSERT [dbo].[Øvrigdag] ([Øvrigdag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (N'Grundlovsdag', 5, 6, 1, 9999) GO INSERT [dbo].[Øvrigdag] ([Øvrigdag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (N'Juleaften', 24, 12, 1, 9999) GO INSERT [dbo].[Øvrigdag] ([Øvrigdag], [FastDag], [FastMåned], [FraÅr], [TilÅr]) VALUES (N'Nytårsaften', 31, 12, 1, 9999) GO SET IDENTITY_INSERT [dbo].[Lukkedag] ON GO INSERT [dbo].[Lukkedag] ([LukkedagId], [Lukkedag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FastUgenummer], [FraÅr], [TilÅr]) VALUES (1, N'Fredag efter Kristi Himmelfartsdag', 40, NULL, NULL, NULL, 1, 9999) GO INSERT [dbo].[Lukkedag] ([LukkedagId], [Lukkedag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FastUgenummer], [FraÅr], [TilÅr]) VALUES (2, N'Grundlovsdag', NULL, 5, 6, NULL, 1, 9999) GO INSERT [dbo].[Lukkedag] ([LukkedagId], [Lukkedag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FastUgenummer], [FraÅr], [TilÅr]) VALUES (3, N'Juleferie', NULL, 24, 12, NULL, 1, 9999) GO INSERT [dbo].[Lukkedag] ([LukkedagId], [Lukkedag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FastUgenummer], [FraÅr], [TilÅr]) VALUES (4, N'Juleferie', NULL, 27, 12, NULL, 1, 9999) GO INSERT [dbo].[Lukkedag] ([LukkedagId], [Lukkedag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FastUgenummer], [FraÅr], [TilÅr]) VALUES (5, N'Juleferie', NULL, 28, 12, NULL, 1, 9999) GO INSERT [dbo].[Lukkedag] ([LukkedagId], [Lukkedag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FastUgenummer], [FraÅr], [TilÅr]) VALUES (6, N'Juleferie', NULL, 29, 12, NULL, 1, 9999) GO INSERT [dbo].[Lukkedag] ([LukkedagId], [Lukkedag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FastUgenummer], [FraÅr], [TilÅr]) VALUES (7, N'Juleferie', NULL, 30, 12, NULL, 1, 9999) GO INSERT [dbo].[Lukkedag] ([LukkedagId], [Lukkedag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FastUgenummer], [FraÅr], [TilÅr]) VALUES (8, N'Juleferie', NULL, 31, 12, NULL, 1, 9999) GO INSERT [dbo].[Lukkedag] ([LukkedagId], [Lukkedag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FastUgenummer], [FraÅr], [TilÅr]) VALUES (9, N'Vinterferie', NULL, NULL, NULL, 7, 1, 9999) GO INSERT [dbo].[Lukkedag] ([LukkedagId], [Lukkedag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FastUgenummer], [FraÅr], [TilÅr]) VALUES (11, N'Sommerferie', NULL, NULL, NULL, 28, 1, 9999) GO INSERT [dbo].[Lukkedag] ([LukkedagId], [Lukkedag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FastUgenummer], [FraÅr], [TilÅr]) VALUES (12, N'Sommerferie', NULL, NULL, NULL, 29, 1, 9999) GO INSERT [dbo].[Lukkedag] ([LukkedagId], [Lukkedag], [AntaldageFraPåskedag], [FastDag], [FastMåned], [FastUgenummer], [FraÅr], [TilÅr]) VALUES (13, N'Sommerferie', NULL, NULL, NULL, 30, 1, 9999) GO SET IDENTITY_INSERT [dbo].[Lukkedag] OFF GO CREATE TABLE [dbo].[Kalender]( [Dato] [date] NOT NULL, [ÅrDato] [int] NULL, [Ugedag] [nvarchar](7) NULL, [Måned] [nvarchar](9) NULL, [Helligdag] [nvarchar](21) NULL, [Øvrigdag] [nvarchar](12) NULL, [ErHelligdag] [bit] NULL, [ErHverdag] [bit] NULL, [ErArbejdsdag] [bit] NULL, [ErLukkedag] [bit] NULL, [ErFørsteMåned] [bit] NULL, [ErSidsteMåned] [bit] NULL, [ErFørsteKvartal] [bit] NULL, [ErSidsteKvartal] [bit] NULL, [DagIUge] [tinyint] NULL, [DagIMåned] [tinyint] NULL, [DagIÅr] [smallint] NULL, [Ugenummer] [tinyint] NULL, [Månedsnummer] [tinyint] NULL, [Kvartalsnummer] [tinyint] NULL, [Halvårsnummer] [tinyint] NULL, [År] [smallint] NULL, [UgedagKort] [nvarchar](3) NULL, [DagHelligdag] [nvarchar](25) NULL, [MånedKort] [nvarchar](3) NULL, [Kvartal] [nvarchar](10) NULL, [Halvår] [nvarchar](9) NULL, [UgeStartÅr] [smallint] NULL, [UgeStartdato] [date] NULL, [UgeSlutdato] [date] NULL, [MånedStartdato] [date] NULL, [MånedSlutdato] [date] NULL, [KvartalStartdato] [date] NULL, [KvartalSlutdato] [date] NULL, [HalvårStartdato] [date] NULL, [HalvårSlutdato] [date] NULL, [ÅrStartdato] [date] NULL, [ÅrSlutdato] [date] NULL, [UgeSidsteHverdagDato] [date] NULL, [MånedSidsteHverdagDato] [date] NULL, [KvartalSidsteHverdagDato] [date] NULL, [HalvårSidsteHverdagDato] [date] NULL, [ÅrSidsteHverdagDato] [date] NULL, [ÅrUge] [int] NULL, [ÅrMåned] [int] NULL, [ÅrKvartal] [int] NULL, [ÅrHalvår] [int] NULL, [DagIUge0] [nvarchar](2) NULL, [DagIMåned0] [nvarchar](2) NULL, [Ugenummer0] [nvarchar](2) NULL, [Månedsnummer0] [nvarchar](2) NULL, [ErUgeOver2Måneder] [bit] NULL, [Årstid] [nvarchar](10) NULL, [Sæson] [nvarchar](9) NULL, [DageIÅr] [smallint] NULL, [DageIHalvår] [smallint] NULL, [DageIKvartal] [smallint] NULL, [DageIMåned] [smallint] NULL, [ÅrUgeDagIUge] [int] NULL, [UgeDagIUge] [int] NULL, [HelUgePrÅr_DagIÅr] [smallint] NULL, [HelUgePrÅr_År] [smallint] NULL, [Arbejdsdagsnummer] [int] NULL, [InsertTime_meta] [datetime2](3) NOT NULL CONSTRAINT [DF_dbo_Kalender_InsertTime_meta] DEFAULT (sysdatetime()), CONSTRAINT [PK_Kalender] PRIMARY KEY CLUSTERED ( [Dato] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO -- ============================================= -- Author: Joakim Dalby -- Create date: 23-11-2014 -- Description: Dannelse af Påskedag dato -- SELECT Påskedag = dbo.Påskedag(2000) -- ============================================= CREATE FUNCTION [dbo].[Påskedag](@år int) RETURNS date AS BEGIN DECLARE @a int, @b int, @c int, @d int, @e int, @k int, @p int, @q int, @m int, @n int, @dag int, @mnd int SET @k = @år / 100 SET @p = (13 + 8 * @k) / 25 SET @q = @k / 4 SET @m = (15 - @p + @k - @q) % 30 SET @n = (4 + @k - @q) % 7 SET @a = @år % 19 SET @b = @år % 4 SET @c = @år % 7 SET @d = (19 * @a + @m) % 30 SET @e = (2 * @b + 4 * @c + 6 * @d + @n) % 7 IF @d + @e <= 9 BEGIN SET @dag = 22 + @d + @e SET @mnd = 3 END ELSE IF (@d = 29) AND (@e = 6) BEGIN SET @dag = 19 SET @mnd = 4 END ELSE IF (@d = 28) And (@e = 6) And (@a > 10) BEGIN SET @dag = 18 SET @mnd = 4 END ELSE BEGIN SET @dag = @d + @e - 9 SET @mnd = 4 END RETURN DATEFROMPARTS(@år, @mnd, @dag) END GO -- ============================================= -- Author: Joakim Dalby -- Create date: 23-11-2014 -- Description: Dannelse af Kalender -- EXEC dbo.Kalender_Build 1900, 2100 -- EXEC dbo.Kalender_Build 1, 9999 -- Changelog: -- 12-03-2023 Folketinget har afskaffet Store Bededag med virkning fra 2024. -- Tabellerne Helligdag og Øvrigdag er udvidet med felter FraÅr og TilÅr som indgår i udfyldelsen af felterne Helligdag og Øvrigdag. -- 27-08-2023 Tilføjet ErLukkedag og Arbejdsdagsnummer. -- ============================================= CREATE PROCEDURE [dbo].[Kalender_Build] @startÅr smallint, @slutÅr smallint AS BEGIN SET NOCOUNT ON SET LANGUAGE Danish -- SELECT * FROM sys.syslanguages SET DATEFIRST 1 -- Mandag er første dag i en uge og får DagIUge = 1 DECLARE @dato date SET @dato = DATEFROMPARTS(@startÅr, 1, 1) TRUNCATE TABLE dbo.Kalender --Løkke der danner en data række per dato. WHILE YEAR(@dato) <= @slutÅr BEGIN INSERT INTO dbo.Kalender(Dato, ErHelligdag, ErHverdag, ErArbejdsdag, ErLukkedag, ErUgeOver2Måneder, ErFørsteMåned, ErSidsteMåned, ErFørsteKvartal, ErSidsteKvartal, ÅrDato, Ugedag, Måned, DagIUge, DagIMåned, DagIÅr, Ugenummer, Månedsnummer, Kvartalsnummer, Halvårsnummer, År, ÅrUge, ÅrMåned, ÅrKvartal, ÅrHalvår) VALUES ( @dato, --Dato 0, --ErHelligdag 0, --ErHverdag 0, --ErArbejdsdag 0, --ErLukkedag 0, --ErUgeOver2Måneder 0, --ErFørsteMåned 0, --ErSidsteMåned 0, --ErFørsteKvartal 0, --ErSidsteKvartal YEAR(@dato) * 10000 + MONTH(@dato) * 100 + DAY(@dato), --ÅrDato DATENAME(weekday, @dato), --Ugedag DATENAME(month, @dato), --Måned DATEPART(weekday, @dato), --DagIUge DATEPART(day, @dato), --DagIMåned DATEPART(dayofyear, @dato),--DagIÅr DATEPART(iso_week, @dato), --Ugenummer, DATEPART(week, @dato) anvender mandag til at bestemme uge 1, Danmark bruger torsdag til at bestemme uge 1 i det nye år. DATEPART(month, @dato), --Månedsnummer DATEPART(quarter, @dato), --Kvartalsnummer (DATEPART(quarter, @dato) + 1) / 2,--Halvårsnummer, heltalsdivision DATEPART(year, @dato), --År -- ÅrUge hvor f.eks. søndag den 1. januar 2012 tilhører uge 52 som kommer fra året 2011 så ÅrUge = 201152 CASE WHEN DATEPART(iso_week, @dato) = 1 AND YEAR(@dato) < YEAR(DATEADD(day, 7, @dato)) THEN YEAR(DATEADD(day,7, @dato)) * 100 + DATEPART(iso_week, @dato) WHEN DATEPART(iso_week, @dato) >= 52 AND YEAR(@dato) > YEAR(DATEADD(day, -7, @dato)) THEN YEAR(DATEADD(day, -7, @dato)) * 100 + DATEPART(iso_week, @dato) ELSE YEAR(@dato) * 100 + DATEPART(iso_week, @dato) END, DATEPART(year, @dato) * 100 + DATEPART(month, @dato), --ÅrMåned DATEPART(year, @dato) * 100 + DATEPART(quarter, @dato), --ÅrKvartal DATEPART(year, @dato) * 100 + (DATEPART(quarter, @dato) + 1) / 2 --ÅrHalvår ) IF @dato <> '99991231' SET @dato = DATEADD(day, 1, @dato) ELSE BREAK END --Løkken slutter. /* -- Egen beregning af Uge og ÅrUge -- ÅrUge, hvor f.eks. søndag den 1. januar 2012 tilhører uge 52 som kommer fra året 2011, derfor ÅrUge = 201152 -- Finder første torsdag i året før som bestemmer uge 1 i Danmark DECLARE @år smallint = IIF(@startÅr = 1, 1, @startÅr-1) DECLARE @uge tinyint SET @dato = DATEFROMPARTS(@år,1,1) WHILE DATEPART(weekday,@dato) <> 4 BEGIN SET @dato = DATEADD(day,1,@dato) END SET @dato = DATEADD(day,4,@dato) IF YEAR(@dato) = 1 BEGIN SET @uge = 0 SET @dato = DATEFROMPARTS(1,1,1) -- mandag uge 1 i år 1. END ELSE BEGIN SET @uge = 1 END WHILE YEAR(@dato) <= @slutÅr BEGIN IF DATEPART(weekday,@dato) = 1 BEGIN IF @dato > '00011230' BEGIN IF YEAR(@dato) < YEAR(DATEADD(day,3,@dato)) OR YEAR(DATEADD(day,3,@dato)) > YEAR(DATEADD(day,-4,@dato)) SET @uge = 1 ELSE SET @uge = @uge + 1 END ELSE BEGIN SET @uge = @uge + 1 END END IF @uge = 1 AND YEAR(@dato) < YEAR(DATEADD(day,7,@dato)) BEGIN SET @år = YEAR(DATEADD(day,7,@dato)) END ELSE BEGIN IF @uge >= 52 AND YEAR(@dato) > YEAR(DATEADD(day,-7,@dato)) SET @år = YEAR(DATEADD(day,-7,@dato)) ELSE SET @år = YEAR(@dato) END IF YEAR(@dato) >= @startÅr BEGIN UPDATE k SET Uge = @uge, ÅrUge = @år * 100 + @uge FROM dbo.Kalender k WHERE Dato = @dato END IF @dato <> '99991231' SET @dato = DATEADD(day,1,@dato) ELSE BREAK END */ -- En række opdateringer af alle dato rækkerne i tabellen dbo.Kalender. -- UgeStartÅr. UPDATE k SET UgeStartÅr = ÅrUge / 100 FROM dbo.Kalender k -- Helligdag som ikke er 24. december juleaften eller 5. juni grundlovsdag ellers har Danmark 9 helligdage når søndag ikke medtages. -- I Helligdag tabellen er de 9 hellige dage defineret enten som faste kalender dage (dag/måned) eller et antal dage før eller efter Påskedag. -- Funktionen dbo.Påskedag beregner datoen for Påskedag for et givet år. -- Når en helligdag f.eks. juledag falder på en søndag, så tilsidesættes Søndag med Juledag. UPDATE k SET Helligdag = 'Søndag', ErHelligdag = 1 FROM dbo.Kalender k WHERE DagIUge = 7 UPDATE k SET Helligdag = h.Helligdag, ErHelligdag = 1 FROM dbo.Kalender k INNER JOIN ( SELECT k.Dato, h.Helligdag FROM dbo.Kalender k INNER JOIN (SELECT å.År, Påskedag = dbo.Påskedag(å.År) FROM (SELECT DISTINCT År FROM dbo.Kalender) å) p ON p.År = k.År INNER JOIN dbo.Helligdag h ON DATEFROMPARTS(k.År, h.FastMåned, h.FastDag) = k.Dato OR -- helligdag på en fast dag og måned DATEDIFF(day, p.Påskedag, k.Dato) = h.AntaldageFraPåskedag -- helligdag antal dage fra Påskedag WHERE k.År BETWEEN h.FraÅr AND h.TilÅr ) h ON h.Dato = k.Dato -- Øvrigdag som ikke er en offentlig helligdag. UPDATE k SET Øvrigdag = ø.Øvrigdag FROM dbo.Kalender k INNER JOIN dbo.Øvrigdag ø ON DATEFROMPARTS(k.År, ø.FastMåned, ø.FastDag) = k.Dato WHERE k.År BETWEEN ø.FraÅr AND ø.TilÅr -- Hverdag er det modsatte af en Helligdag. UPDATE k SET ErHverdag = 1 FROM dbo.Kalender k WHERE ErHelligdag = 0 -- Arbejdsdag er mandag til fredag og ikke en helligdag og ikke en øvrig dag. UPDATE k SET ErArbejdsdag = 1 FROM dbo.Kalender k WHERE DagIUge BETWEEN 1 AND 5 AND ErHelligdag = 0 AND Øvrigdag IS NULL -- Lukkedag. UPDATE k SET ErLukkedag = 1 FROM dbo.Kalender k INNER JOIN ( SELECT k.Dato, h.Lukkedag FROM dbo.Kalender k INNER JOIN (SELECT å.År, Påskedag = dbo.Påskedag(å.År) FROM (SELECT DISTINCT År FROM dbo.Kalender) å) p ON p.År = k.År INNER JOIN dbo.Lukkedag h ON DATEFROMPARTS(k.År, h.FastMåned, h.FastDag) = k.Dato OR -- Lukkedag på en fast dag og måned DATEDIFF(day, p.Påskedag, k.Dato) = h.AntaldageFraPåskedag OR -- Lukkedag antal dage fra Påskedag k.Dato IN (SELECT Dato FROM dbo.Kalender u WHERE u.ÅrUge = (k.År * 100) + h.FastUgenummer) -- Lukkedag i fast uge WHERE k.År BETWEEN h.FraÅr AND h.TilÅr ) h ON h.Dato = k.Dato -- UgedagKort og Ugedag med stort bogstav fra Ugedag tabellen. UPDATE k SET UgedagKort = d.UgedagKort, Ugedag = d.Ugedag, DagHelligdag = d.UgedagKort + IIF(k.Helligdag IS NOT NULL,'/'+k.Helligdag,'') FROM dbo.Kalender k INNER JOIN dbo.Ugedag d ON d.DagIUge = k.DagIUge -- MånednavnKort, Kvartalnavn og Halvårnavn samt Månednavn med stort bogstav fra Måned tabellen plus Årstid. UPDATE k SET MånedKort = m.MånedKort, Måned = m.Måned, Kvartal = m.Kvartal, Halvår = m.Halvår, Årstid = m.Årstid FROM dbo.Kalender k INNER JOIN dbo.Måned m ON m.Månedsnummer = k.Månedsnummer /* -- ÅrMåned, ÅrKvartal, ÅrHalvår. UPDATE k SET ÅrMåned = År * 100 + Måned, ÅrKvartal = År * 100 + Kvartal, ÅrHalvår = År * 100 + Halvår FROM dbo.Kalender k */ -- UgeStartdato og UgeSlutdato. UPDATE k SET UgeStartdato = d.minDato, UgeSlutdato = d.maxDato FROM dbo.Kalender k INNER JOIN ( SELECT ÅrUge, minDato = MIN(Dato), maxDato = MAX(Dato) FROM dbo.Kalender GROUP BY ÅrUge ) d ON d.ÅrUge = k.ÅrUge -- MånedStartdato og MånedSlutdato. UPDATE k SET MånedStartdato = d.minDato, MånedSlutdato = d.maxDato FROM dbo.Kalender k INNER JOIN ( SELECT ÅrMåned, minDato = MIN(Dato), maxDato = MAX(Dato) FROM dbo.Kalender GROUP BY ÅrMåned ) d ON d.ÅrMåned = k.ÅrMåned -- KvartalStartdato og KvartalSlutdato. UPDATE k SET KvartalStartdato = d.minDato, KvartalSlutdato = d.maxDato FROM dbo.Kalender k INNER JOIN ( SELECT ÅrKvartal, minDato = MIN(Dato), maxDato = MAX(Dato) FROM dbo.Kalender GROUP BY ÅrKvartal ) d ON d.ÅrKvartal = k.ÅrKvartal -- HalvårStartdato og HalvårSlutdato. UPDATE k SET HalvårStartdato = d.minDato, HalvårSlutdato = d.maxDato FROM dbo.Kalender k INNER JOIN ( SELECT ÅrHalvår, minDato = MIN(Dato), maxDato = MAX(Dato) FROM dbo.Kalender GROUP BY ÅrHalvår ) d ON d.ÅrHalvår = k.ÅrHalvår -- ÅrStartdato og ÅrSlutdato. UPDATE k SET ÅrStartdato = d.minDato, ÅrSlutdato = d.maxDato FROM dbo.Kalender k INNER JOIN ( SELECT År, minDato = MIN(Dato), maxDato = MAX(Dato) FROM dbo.Kalender GROUP BY År ) d ON d.År = k.År -- UgeSidsteHverdagDato. UPDATE k SET UgeSidsteHverdagDato = d.maxDato FROM dbo.Kalender k INNER JOIN ( SELECT ÅrUge, maxDato = MAX(Dato) FROM dbo.Kalender WHERE ErHverdag = 1 GROUP BY ÅrUge ) d ON d.ÅrUge = k.ÅrUge -- MånedSidsteHverdagDato. UPDATE k SET MånedSidsteHverdagDato = d.maxDato FROM dbo.Kalender k INNER JOIN ( SELECT ÅrMåned, maxDato = MAX(Dato) FROM dbo.Kalender WHERE ErHverdag = 1 GROUP BY ÅrMåned ) d ON d.ÅrMåned = k.ÅrMåned -- KvartalSidsteHverdagDato. UPDATE k SET KvartalSidsteHverdagDato = d.maxDato FROM dbo.Kalender k INNER JOIN ( SELECT ÅrKvartal, maxDato = MAX(Dato) FROM dbo.Kalender WHERE ErHverdag = 1 GROUP BY ÅrKvartal ) d ON d.ÅrKvartal = k.ÅrKvartal -- HalvårSidsteHverdagDato. UPDATE k SET HalvårSidsteHverdagDato = d.maxDato FROM dbo.Kalender k INNER JOIN ( SELECT ÅrHalvår, maxDato = MAX(Dato) FROM dbo.Kalender WHERE ErHverdag = 1 GROUP BY ÅrHalvår ) d ON d.ÅrHalvår = k.ÅrHalvår -- ÅrSidsteHverdagDato. UPDATE k SET ÅrSidsteHverdagDato = d.maxDato FROM dbo.Kalender k INNER JOIN ( SELECT År, maxDato = MAX(Dato) FROM dbo.Kalender WHERE ErHverdag = 1 GROUP BY År ) d ON d.År = k.År -- ErFørsteMåned og ErSidsteMåned UPDATE k SET ErFørsteMåned = 1 FROM dbo.Kalender k WHERE MånedStartdato = Dato UPDATE k SET ErSidsteMåned = 1 FROM dbo.Kalender k WHERE MånedSlutdato = Dato -- ErFørsteKvartal og ErSidsteKvartal UPDATE k SET ErFørsteKvartal = 1 FROM dbo.Kalender k WHERE KvartalStartdato = Dato UPDATE k SET ErSidsteKvartal = 1 FROM dbo.Kalender k WHERE KvartalSlutdato = Dato -- DagIUge0, DagIMåned0, Uge0, Måned0. UPDATE k SET DagIUge0 = RIGHT('0' + CAST(DagIUge AS nvarchar(2)),2), DagIMåned0 = RIGHT('0' + CAST(DagIMåned AS nvarchar(2)),2), Ugenummer0 = RIGHT('0' + CAST(Ugenummer AS nvarchar(2)),2), Månedsnummer0 = RIGHT('0' + CAST(Månedsnummer AS nvarchar(2)),2) FROM dbo.Kalender k -- UgeOver2Måneder. UPDATE k SET ErUgeOver2Måneder = 1 FROM dbo.Kalender k INNER JOIN ( SELECT ÅrUge FROM dbo.Kalender GROUP BY ÅrUge HAVING COUNT(DISTINCT ÅrMåned) = 2 ) u ON u.ÅrUge = k.ÅrUge -- Sæson. UPDATE k SET Sæson = CASE WHEN Månedsnummer BETWEEN 1 AND 6 THEN CAST(År-1 AS nvarchar(4)) + '/' + CAST(År AS nvarchar(4)) WHEN Månedsnummer BETWEEN 7 AND 12 THEN CAST(År AS nvarchar(4)) + '/' + CAST(IIF(År=9999,9999,År+1) AS nvarchar(4)) END FROM dbo.Kalender k -- DageI. ;WITH dage AS ( SELECT Dato, DageIÅr = COUNT(1) OVER(PARTITION BY År), DageIHalvår = COUNT(1) OVER(PARTITION BY ÅrHalvår), DageIKvartal = COUNT(1) OVER(PARTITION BY ÅrKvartal), DageIMåned = COUNT(1) OVER(PARTITION BY ÅrMåned) FROM dbo.Kalender ) UPDATE k SET DageIÅr = dage.DageIÅr, DageIHalvår = dage.DageIHalvår, DageIKvartal = dage.DageIKvartal, DageIMåned = dage.DageIMåned FROM dbo.Kalender k INNER JOIN dage ON dage.Dato = k.Dato /* Joakim Dalby opfindelse: ÅrUgeDagIUge til at sammenligne uge 7 i 2016 med uge 7 i 2015 uden at anvende datoer, fordi ugens datoer er forskellige år til år i forhold til datoer i en måned som altid er det samme. Derfor skal fact tabellen have ÅrUgeDagIUge og der skal laves en ny dimension Uge med et hierarki År -> ArUge -> ÅrUgeDagIUge. Det kan også være, at man ikke ønsker årstallet, så er UgeDagIUge svaret hvor 11 = uge 1 mandag, 12 = uge 1 tirsdag, 73 = uge 7 onsdag, 407 = uge 40 søndag og 537 uge 53 søndag, d.v.s. 371 muligheder fordi intet årstal. De 371 kan være i en dimension kaldet Visningsuge med attributten visningsdag: Uge 1 mandag og med et hierarki og anden attribut visningsuge: Uge 1 til at filtrere visningdage med. En anden dimension kaldet År fordeler data på de forskellige år og sammen med Visningsdag kan man sammenligne ugerne mellem årene f.eks. uge 7 i år 2015 og 2016 selvom datoerne i disse to uger er meget forskellige. Eller sammenligne uge 1 i 2015 og i 2016, fordi uge 1 i 2015 starter 29-12-2014 til 04-01-2015 d.v.s. juleferie og uge 1 i 2016 starter 04-01-2016 til 10-01-2016 d.v.s. en arbejdsuge. Uge 7 i 2010 er fra 2010-02-15 til 2010-02-21 og uge 7 i 2019 er fra 2019-02-11 til 2019-02-17 har begge perioder samme værdi i feltet UgeDagIUge fra 71 til 77 så de to perioder kan sammenlignes via feltet UgeDagIUge. */ UPDATE k SET ÅrUgeDagIUge = (ÅrUge * 10) + DagIUge, UgeDagIUge = (Ugenummer * 10) + DagIUge FROM dbo.Kalender k /* Leap week calendar: Hvor eksempelvis mandag 29-12-2014 og mandag 04-01-2016 har samme HelUgePrÅr_DagIÅr = 1. Med et helt antal uger hvert år, og med hvert år på samme ugedag. intercalary week or leap week. Uge 7 i 2010 er fra 2010-02-15 til 2010-02-21 og uge 7 i 2019 er fra 2019-02-11 til 2019-02-17 har begge perioder samme værdi i feltet HelUgePrÅr_DagIÅr fra 43 til 49 så de to perioder kan sammenlignes via feltet HelUgePrÅr_DagIÅr. Følgende datoer søndage 2005-01-02, 2010-01-03, 2016-01-03, 2021-01-03, 2027-01-03 har feltet HelUgePrÅr_DagIÅr = 371 og forskellige år i feltet HelUgePrÅr_År har et årstal et år mindre end datoen. Feltet UgeDagIUge = 537 derfor er søndagene i samme uge = 53. https://en.wikipedia.org/wiki/Leap_week_calendar https://en.wikipedia.org/wiki/ISO_week_date */ UPDATE k SET HelUgePrÅr_DagIÅr = (DATEPART(iso_week, Dato) - 1) * 7 + DATEPART(weekday, Dato), HelUgePrÅr_År = YEAR(DATEADD(day, 26 - DATEPART(iso_week,Dato), Dato)) FROM dbo.Kalender k -- Arbejdsdagsnummer som et fortløbende nummer på hverdage som hverken er helligdag og lukkedag. ;WITH datoer AS ( SELECT Dato, Arbejdsdagsnummer = ROW_NUMBER() OVER(ORDER BY Dato) FROM dbo.Kalender WHERE DagIUge BETWEEN 1 AND 5 AND ErHelligdag = 0 AND ErLukkedag = 0 ) UPDATE k SET Arbejdsdagsnummer = d.Arbejdsdagsnummer FROM dbo.Kalender k INNER JOIN datoer d ON d.Dato = k.Dato WHERE DagIUge BETWEEN 1 AND 5 AND ErHelligdag = 0 AND ErLukkedag = 0 -- Arbejdsdagsnummer gentages som dubletter på datoer i weekender, helligdage og lukkedage, hvorved Arbejdsdagsnummer altid er udfyldt. DECLARE @i int = 0 WHILE @i < 30 BEGIN ;WITH datoer AS ( SELECT a.Dato, b.Arbejdsdagsnummer FROM dbo.Kalender a INNER JOIN dbo.Kalender b ON b.Dato = DATEADD(day,-1,a.Dato) WHERE a.Arbejdsdagsnummer IS NULL ) UPDATE k SET Arbejdsdagsnummer = d.Arbejdsdagsnummer FROM dbo.Kalender k INNER JOIN datoer d ON d.Dato = k.Dato WHERE k.Arbejdsdagsnummer IS NULL SET @i = @i + 1 END UPDATE k SET Arbejdsdagsnummer = 0 FROM dbo.Kalender k WHERE Dato = DATEFROMPARTS(@startÅr, 1, 1) /* Beregning af en Fristdato ud fra en dato og fire arbejdsdage ved at kalde en scalar-valued function SELECT Fristdato = dbo.BeregnetDato('2023-03-31', 4, 'Arbejdsdage') */ END GO -- ============================================= -- Author: Joakim Dalby -- Create date: 27-08-2023 -- Description: Returnerer en beregnet dato ud fra en dato, et antal dage og en type som er enten 'Kalenderdage' eller 'Arbejdsdage'. -- SELECT dbo.BeregnetDato('2023-01-01', 90, 'Kalenderdage') -- SELECT dbo.BeregnetDato('2023-01-01', 90, 'Arbejdsdage') -- Changelog: -- ============================================= CREATE FUNCTION [dbo].[BeregnetDato](@Dato date, @AntalDage int, @Type varchar(50)) RETURNS date AS BEGIN DECLARE @BeregnetDato date = NULL IF @Type = 'Kalenderdage' BEGIN SELECT @BeregnetDato = DATEADD(day, @AntalDage, @Dato) END IF @Type = 'Arbejdsdage' BEGIN SELECT @BeregnetDato = MIN(b.Dato) FROM dbo.Kalender a INNER JOIN dbo.Kalender b ON b.Arbejdsdagsnummer = (a.Arbejdsdagsnummer + @AntalDage) WHERE a.Dato = @Dato END RETURN @BeregnetDato END GO