создайте результирующий набор календарных дат

#sql-server #tsql #sql-server-2008

#sql-сервер #tsql #sql-server-2008

Вопрос:

Я должен использовать хранимую процедуру для заполнения календаря на 10 лет в базе данных SQL!

Мне следует заполнить записями три столбца: дата, день недели или выходные, название дня (понедельник, …).

Кто-нибудь может мне помочь?

Ответ №1:

Вы можете сделать это динамически следующим образом:

 WITH Dates AS (
        SELECT CONVERT(DATE, getdate()) as [Date]
        UNION ALL 
        SELECT DATEADD(DAY, 1, [Date])
        FROM Dates
        where Date < dateadd(yy, 10, getdate())

) 
SELECT [Date]
FROM Dates
OPTION (MAXRECURSION 4000)
  

Ответ №2:

попробуйте эту версию (заполняет datetime и добавляет все запрошенные столбцы):

 ;WITH Dates AS (
        SELECT DATEADD(day,DATEDIFF(day,0,GETDATE()),0) as DateOf,
            CASE WHEN datename(weekday,getdate()) IN ('Saturday','Sunday') THEN 'Weekend'
                 ELSE 'WeekDay' 
            END DayType,
            datename(weekday,getdate()) DayOfWeekName
        UNION ALL 
        SELECT DateOf 1,
            CASE WHEN datename(weekday,DateOf 1) IN ('Saturday','Sunday') THEN 'Weekend'
                 ELSE 'WeekDay' 
            END DayType,
            datename(weekday,DateOf 1) DayOfWeekName
        FROM Dates
        where DateOf < dateadd(yy, 10, getdate())

) 
SELECT DateOf,DayType,DayOfWeekName
FROM Dates
OPTION (MAXRECURSION 4000)
  

для вставки в таблицу попробуйте следующее:

 DECLARE @DateTable table (DateOf datetime, DayType char(7), DayOfWeekName varchar(10))

;WITH Dates AS (
        SELECT DATEADD(day,DATEDIFF(day,0,GETDATE()),0) as DateOf,
            CASE WHEN datename(weekday,getdate()) IN ('Saturday','Sunday') THEN 'Weekend'
                 ELSE 'WeekDay' 
            END DayType,
            datename(weekday,getdate()) DayOfWeekName
        UNION ALL 
        SELECT DateOf 1,
            CASE WHEN datename(weekday,DateOf 1) IN ('Saturday','Sunday') THEN 'Weekend'
                 ELSE 'WeekDay' 
            END DayType,
            datename(weekday,DateOf 1) DayOfWeekName
        FROM Dates
        where DateOf < dateadd(yy, 10, getdate())

)
INSERT INTO  @DateTable (DateOf,DayType,DayOfWeekName)
    SELECT DateOf,DayType,DayOfWeekName
    FROM Dates
    OPTION (MAXRECURSION 4000)
  

выберите топ-10 * из @DateTable

ВЫВОД:

 DateOf                  DayType DayOfWeekName
----------------------- ------- -------------
2011-05-16 00:00:00.000 WeekDay Monday
2011-05-17 00:00:00.000 WeekDay Tuesday
2011-05-18 00:00:00.000 WeekDay Wednesday
2011-05-19 00:00:00.000 WeekDay Thursday
2011-05-20 00:00:00.000 WeekDay Friday
2011-05-21 00:00:00.000 Weekend Saturday
2011-05-22 00:00:00.000 Weekend Sunday
2011-05-23 00:00:00.000 WeekDay Monday
2011-05-24 00:00:00.000 WeekDay Tuesday
2011-05-25 00:00:00.000 WeekDay Wednesday

(10 row(s) affected)
  

Ответ №3:

Я определил это как проблему с таблицей подсчета. Я использую spt_values из Master в качестве моей таблицы подсчета. Он доходит только до 2048 года, чего достаточно для данных на 5,5 лет. Вы можете создать свою собственную таблицу подсчета с таким количеством чисел, сколько вам нужно.

 Declare @startDate Date = '1/1/2011'; 

SELECT DateAdd(d, number, @startDate) [Date], 
       CASE WHEN DATEPART(dw, DateAdd(d, number, @startDate)) IN (1,7) THEN 'Weekend' ELSE 'Weekday' END [WeekDayEnd], 
       DateName(weekday, DateAdd(d, number, @startDate)) DayOfWeek
FROM spt_values 
WHERE type = 'P';
  

Это приводит к следующим результатам:

 Date        WeekDayEnd  DayOfWeek
2011-01-01  Weekend     Saturday
2011-01-02  Weekend     Sunday
2011-01-03  Weekday     Monday
2011-01-04  Weekday     Tuesday
2011-01-05  Weekday     Wednesday
2011-01-06  Weekday     Thursday
2011-01-07  Weekday     Friday
2011-01-08  Weekend     Saturday
2011-01-09  Weekend     Sunday
2011-01-10  Weekday     Monday
  

Ответ №4:

ИСПОЛЬЗУЙТЕ ЭТО

 set nocount on

SET DATEFIRST 7;

go
select date,
datename(dw,datepart(dw,date)) Day,
datepart(dw,date) Day,
'Segment' = case  
when datepart(dw,date)in (5,6) then 'WEEK_END' else 'Week_day' end
from calenderdate

set nocount off
  
 > set nocount on
> 
> select  date,
> substring(cast(datename(dw,datepart(dw,date))as
> varchar(10)),1,3) Day, 'Segment' =
> case   when datepart(dw,date)in (5,6)
> then 'WEEK_END' else 'Week_day' end
> from calenderdate
> 
> set nocount off
  

вывод

1/1/2011 Понедельник 7-й день недели 1/2/2011 Вторник 1-й день недели