假设我想在桌子上存储数千天,我将如何从日历中提取.
解决方法
以下是可以在sql Server中使用的通用脚本.只是修改开始和结束日期:
IF EXISTS (SELECT * FROM information_schema.tables WHERE Table_Name = 'Calendar' AND Table_Type = 'BASE TABLE') BEGIN DROP TABLE [Calendar] END CREATE TABLE [Calendar] ( [CalendarDate] DATETIME ) DECLARE @StartDate DATETIME DECLARE @EndDate DATETIME SET @StartDate = GETDATE() SET @EndDate = DATEADD(d,365,@StartDate) WHILE @StartDate <= @EndDate BEGIN INSERT INTO [Calendar] ( CalendarDate ) SELECT @StartDate SET @StartDate = DATEADD(dd,1,@StartDate) END
如果你想要一个更高级的日历在这里是一个我在网上发现:
CREATE SCHEMA Auxiliary -- We put our auxiliary tables and stuff in a separate schema -- One of the great new things in sql Server 2005 go CREATE FUNCTION Auxiliary.Computus -- Computus (Latin for computation) is the calculation of the date of -- Easter in the Christian calendar -- http://en.wikipedia.org/wiki/Computus -- I'm using the Meeus/Jones/Butcher Gregorian algorithm ( @Y INT -- The year we are calculating easter sunday for ) RETURNS DATETIME AS BEGIN DECLARE @a INT,@b INT,@c INT,@d INT,@e INT,@f INT,@g INT,@h INT,@i INT,@k INT,@L INT,@m INT SET @a = @Y % 19 SET @b = @Y / 100 SET @c = @Y % 100 SET @d = @b / 4 SET @e = @b % 4 SET @f = (@b + 8) / 25 SET @g = (@b - @f + 1) / 3 SET @h = (19 * @a + @b - @d - @g + 15) % 30 SET @i = @c / 4 SET @k = @c % 4 SET @L = (32 + 2 * @e + 2 * @i - @h - @k) % 7 SET @m = (@a + 11 * @h + 22 * @L) / 451 RETURN(DATEADD(month,((@h + @L - 7 * @m + 114) / 31)-1,cast(cast(@Y AS VARCHAR) AS Datetime)) + ((@h + @L - 7 * @m + 114) % 31)) END GO CREATE TABLE [Auxiliary].[Calendar] ( -- This is the calendar table [Date] datetime NOT NULL,[Year] int NOT NULL,[Quarter] int NOT NULL,[Month] int NOT NULL,[Week] int NOT NULL,[Day] int NOT NULL,[DayOfYear] int NOT NULL,[Weekday] int NOT NULL,[Fiscal_Year] int NOT NULL,[Fiscal_Quarter] int NOT NULL,[Fiscal_Month] int NOT NULL,[KindOfDay] varchar(10) NOT NULL,[Description] varchar(50) NULL,PRIMARY KEY CLUSTERED ([Date]) ) GO ALTER TABLE [Auxiliary].[Calendar] -- In Celkoish style I'm manic about constraints (Never use em ;-)) -- http://www.celko.com/ ADD CONSTRAINT [Calendar_ck] CHECK ( ([Year] > 1900) AND ([Quarter] BETWEEN 1 AND 4) AND ([Month] BETWEEN 1 AND 12) AND ([Week] BETWEEN 1 AND 53) AND ([Day] BETWEEN 1 AND 31) AND ([DayOfYear] BETWEEN 1 AND 366) AND ([Weekday] BETWEEN 1 AND 7) AND ([Fiscal_Year] > 1900) AND ([Fiscal_Quarter] BETWEEN 1 AND 4) AND ([Fiscal_Month] BETWEEN 1 AND 12) AND ([KindOfDay] IN ('HOLIDAY','SATURDAY','SUNDAY','BANKDAY'))) GO SET DATEFIRST 1; -- I want my table to contain datedata acording to ISO 8601 -- http://en.wikipedia.org/wiki/ISO_8601 -- thus first day of a week is monday WITH Dates(Date) -- A recursive CTE that produce all dates between 1999 and 2020-12-31 AS ( SELECT cast('1999' AS DateTime) Date -- sql Server supports the ISO 8601 format so this is an unambigIoUs shortcut for 1999-01-01 UNION ALL -- http://msdn2.microsoft.com/en-us/library/ms190977.aspx SELECT (Date + 1) AS Date FROM Dates WHERE Date < cast('2021' AS DateTime) -1 ),DatesAndThursdayInWeek(Date,Thursday) -- The weeks can be found by counting the thursdays in a year so we find -- the thursday in the week for a particular date AS ( SELECT Date,CASE DATEPART(weekday,Date) WHEN 1 THEN Date + 3 WHEN 2 THEN Date + 2 WHEN 3 THEN Date + 1 WHEN 4 THEN Date WHEN 5 THEN Date - 1 WHEN 6 THEN Date - 2 WHEN 7 THEN Date - 3 END AS Thursday FROM Dates ),Weeks(Week,Thursday) -- Now we produce the weeknumers for the thursdays -- ROW_NUMBER is new to sql Server 2005 AS ( SELECT ROW_NUMBER() OVER(partition by year(Date) order by Date) Week,Thursday FROM DatesAndThursdayInWeek WHERE DATEPART(weekday,Date) = 4 ) INSERT INTO Auxiliary.Calendar SELECT d.Date,YEAR(d.Date) AS Year,DATEPART(Quarter,d.Date) AS Quarter,MONTH(d.Date) AS Month,w.Week,DAY(d.Date) AS Day,DATEPART(DayOfYear,d.Date) AS DayOfYear,DATEPART(Weekday,d.Date) AS Weekday,-- Fiscal year may be different to the actual year in Norway the are the same -- http://en.wikipedia.org/wiki/Fiscal_year YEAR(d.Date) AS Fiscal_Year,d.Date) AS Fiscal_Quarter,MONTH(d.Date) AS Fiscal_Month,CASE -- Holidays in Norway -- For other countries and states: Wikipedia - List of holidays by country -- http://en.wikipedia.org/wiki/List_of_holidays_by_country WHEN (DATEPART(DayOfYear,d.Date) = 1) -- New Year's Day OR (d.Date = Auxiliary.Computus(YEAR(Date))-7) -- Palm Sunday OR (d.Date = Auxiliary.Computus(YEAR(Date))-3) -- Maundy Thursday OR (d.Date = Auxiliary.Computus(YEAR(Date))-2) -- Good Friday OR (d.Date = Auxiliary.Computus(YEAR(Date))) -- Easter Sunday OR (d.Date = Auxiliary.Computus(YEAR(Date))+39) -- Ascension Day OR (d.Date = Auxiliary.Computus(YEAR(Date))+49) -- Pentecost OR (d.Date = Auxiliary.Computus(YEAR(Date))+50) -- Whitmonday OR (MONTH(d.Date) = 5 AND DAY(d.Date) = 1) -- Labour day OR (MONTH(d.Date) = 5 AND DAY(d.Date) = 17) -- Constitution day OR (MONTH(d.Date) = 12 AND DAY(d.Date) = 25) -- Cristmas day OR (MONTH(d.Date) = 12 AND DAY(d.Date) = 26) -- Boxing day THEN 'HOLIDAY' WHEN DATEPART(Weekday,d.Date) = 6 THEN 'SATURDAY' WHEN DATEPART(Weekday,d.Date) = 7 THEN 'SUNDAY' ELSE 'BANKDAY' END KindOfDay,CASE -- Description of holidays in Norway WHEN (DATEPART(DayOfYear,d.Date) = 1) THEN 'New Year''s Day' WHEN (d.Date = Auxiliary.Computus(YEAR(Date))-7) THEN 'Palm Sunday' WHEN (d.Date = Auxiliary.Computus(YEAR(Date))-3) THEN 'Maundy Thursday' WHEN (d.Date = Auxiliary.Computus(YEAR(Date))-2) THEN 'Good Friday' WHEN (d.Date = Auxiliary.Computus(YEAR(Date))) THEN 'Easter Sunday' WHEN (d.Date = Auxiliary.Computus(YEAR(Date))+39) THEN 'Ascension Day' WHEN (d.Date = Auxiliary.Computus(YEAR(Date))+49) THEN 'Pentecost' WHEN (d.Date = Auxiliary.Computus(YEAR(Date))+50) THEN 'Whitmonday' WHEN (MONTH(d.Date) = 5 AND DAY(d.Date) = 1) THEN 'Labour day' WHEN (MONTH(d.Date) = 5 AND DAY(d.Date) = 17) THEN 'Constitution day' WHEN (MONTH(d.Date) = 12 AND DAY(d.Date) = 25) THEN 'Cristmas day' WHEN (MONTH(d.Date) = 12 AND DAY(d.Date) = 26) THEN 'Boxing day' END Description FROM DatesAndThursdayInWeek d -- This join is for getting the week into the result set inner join Weeks w on d.Thursday = w.Thursday OPTION(MAXRECURSION 0) GO CREATE FUNCTION Auxiliary.Numbers ( @AFrom INT,@ATo INT,@AIncrement INT ) RETURNS @RetNumbers TABLE ( [Number] int PRIMARY KEY NOT NULL ) AS BEGIN WITH Numbers(n) AS ( SELECT @AFrom AS n UNION ALL SELECT (n + @AIncrement) AS n FROM Numbers WHERE n < @ATo ) INSERT @RetNumbers SELECT n from Numbers OPTION(MAXRECURSION 0) RETURN; END GO CREATE FUNCTION Auxiliary.iNumbers ( @AFrom INT,@AIncrement INT ) RETURNS TABLE AS RETURN( WITH Numbers(n) AS ( SELECT @AFrom AS n UNION ALL SELECT (n + @AIncrement) AS n FROM Numbers WHERE n < @ATo ) SELECT n AS Number from Numbers ) GO