SQL事件日历

时间:2018-08-17 14:54:40

标签: sql sql-server

我有一个试图在SQL中创建的事件日历。问题是我不能像日期那样旋转事件。有没有办法做两个枢纽或类似的活动,以便事件在日期下排成一行。

这是枢轴之前的桌子

YearNum MonthName   week_number DayNum  DayofWeek   EventStart  EventSubject    EventLocation   EventDate
2018    August                  33  14  Tuesday         NULL    NULL    NULL    NULL
2018    August                  33  15  Wednesday       NULL    NULL    NULL    NULL
2018    August                  33  16  Thursday        13:00   Dan's Birthday  EC-E    2018-08-16
2018    August                  33  17  Friday          NULL    NULL    NULL    NULL
2018    August                  33  18  Saturday        NULL    NULL    NULL    NULL
2018    August                  34  19  Sunday          NULL    NULL    NULL    NULL
2018    August                  34  20  Monday          NULL    NULL    NULL    NULL

枢轴之后,就是这样

enter image description here

这是我目前正在使用的SQL查询:

SELECT MonthName, YearNum, Sunday, Monday,Tuesday,Wednesday,Thursday,Friday,Saturday, EventStart, EventSubject, EventLocation, EventDate
FROM 
(
SELECT        CalendarDates.YearNum, CalendarDates.MonthName, DATEPART(WEEK, CalendarDates.StandardDate) AS week_number, CalendarDates.DayNum, 
                         CalendarDates.DayofWeek, EventList.EventStart, EventList.EventSubject, EventList.EventLocation, EventList.EventDate
FROM            (SELECT        EventStart, EventSubject, EventLocation, EventDate
                          FROM            EventList AS EventList_1) AS EventList RIGHT OUTER JOIN
                         CalendarDates ON EventList.EventDate = CalendarDates.StandardDate
WHERE        (CalendarDates.MonthNum = '8') AND (CalendarDates.YearNum = '2018')
)
pivotDates
PIVOT (MIN(DayNum) FOR DayofWeek IN (Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday)) AS Pivots

这是输出的样子 enter image description here

1 个答案:

答案 0 :(得分:1)

这个问题可以在表示层中得到更好的解决,因为SQL在计算/筛选数据方面做得很好,而在用户界面中却做得很好。

无论如何,请尝试以下操作:

DECLARE @CurrentMonth   INT = 8,
        @CurrentYear    INT = 2018

;WITH   RawData AS  -- Your original appointment dates
(
        SELECT  CAST('2018-08-16' AS DATE)  Date, 
                CAST('13:00'      AS TIME)  Start, 
                'Someone birthday'          Subject, 
                'Location'                  Location 
),      AllMonthDays AS -- list of all days in the filtered month
(
        SELECT  CAST(CAST(@CurrentYear  AS VARCHAR) + '-' + 
                     CAST(@CurrentMonth AS VARCHAR) + '-01' AS DATE) Date UNION ALL
        SELECT  DATEADD(D, +1, Date)
        FROM    AllMonthDays
        WHERE   MONTH(DATEADD(D, +1, Date)) = @CurrentMonth
),      CalendarData AS -- Adds the weekday name, week numbering and appointment data
(
        SELECT      AllMonthDays.Date,
                    DATEPART(WEEK   , AllMonthDays.Date) WeekNumber,
                    DATENAME(DW     , AllMonthDays.Date) WeekdayName,
                    NULLIF(CONCAT(
                        CAST(RawData.Start AS CHAR(5)), ' ', 
                        RawData.Subject, '@ ', RawData.Location), ' @ ') Appointment
        FROM        AllMonthDays
        LEFT JOIN   RawData
                ON  RawData.Date = AllMonthDays.Date
),      CalendarFormat AS   -- PIVOT the data, putting the weekdays as columns
(
        SELECT  *
        FROM    CalendarData 
        PIVOT
        (   --MIN(Date) FOR         -- uncomment this to a better understanding
            MIN(Appointment) FOR    -- weird part: using MIN in a text column
            WeekdayName IN
            (   [Sunday], [Monday], [Tuesday],
                [Wednesday], [Thursday], [Friday], [Saturday]
            )
        ) p
)
SELECT      MIN(WeekNumber ) [WeekNumber],
            MIN([Sunday]   ) [Sunday], 
            MIN([Monday]   ) [Monday], 
            MIN([Tuesday]  ) [Tuesday], 
            MIN([Wednesday]) [Wednesday], 
            MIN([Thursday] ) [Thursday], 
            MIN([Friday]   ) [Friday], 
            MIN([Saturday] ) [Saturday]
FROM        CalendarFormat
GROUP BY    WeekNumber  -- suppress duplications
ORDER BY    WeekNumber