2013-12-20 2 views
1

Итак, у меня есть набор часов для определенного набора дней (позволяет назвать его расписанием), это расписание описывает общий шаблон. Однако иногда есть то, что я буду называть исключениями, когда расписание растет или ограничивается.SQL Date/Time Manipulation

Например:

Расписание Понедельник 7:00 AM - 4:00 PM, 5:00 PM - 9:00 PM

Исключения для этого следующий понедельник, в частности: 6:00 PM - 7:00 PM

Можно ли манипулировать часами в SQL Query, чтобы вернуться 7:00 - 16:00, с 5:00 до 18:00 и с 19:00 до 21:00 , Я понимаю, что это возможно с помощью таблицы temp и трех разных запросов, но я надеялся сделать это более элегантно.

Другим вариантом может быть все это в логике C# ... Я буду очень признателен за любую помощь в решении этой задачи планирования.

Источник таблица (пожалуйста, обратите внимание, что я до сих пор Открыт для изменения структуры при необходимости)

Schedule - A user can set up a named schedule 
Id 
Name 


ScheduleDates - Describes the dates range(s) a schedule is active 
Id 
ScheduleId 
StartDate 
EndDate 


ScheduleEntries - Describe the schedule that describes most 
of the dates in the schedule 
ScheduleId 
StartTime 
EndTime 
DayId (Describes which day of the week) 


Exception 
Id 
Reason 
StartTime 
EndTime 
+3

Опишите исходную таблицу (ы). –

+0

Являются ли ваши поля только даты или даты? Я спрашиваю, потому что нет необходимости в таблице ScheduleEntries, если ваши поля имеют дату и время. У вас уже есть день на старте –

+1

Является ли исключение предназначено только для определенной функции ScheduleEntry? Если это так, я бы добавил поле Id в таблицу ScheduleEntry и ссылку на внешний ключ для ScheduleId в Exception. Я также добавил бы поле DayId в Exception. Затем вы могли бы присоединиться к ScheduleEntries в Exception и использовать его как переопределение. – Jordan

ответ

0

Пожалуйста, поставьте ваши предложения, как и в то, что вы уже поняли, мы можем определенно сделать на этом. Тем не менее мое предложение состояло в том, чтобы сделать proc и использовать функцию Getdate и создать algo, чтобы проверить, не попадает ли это время под ваше исключение. Отдых, я уверен, что вы можете понять. :)

0

Вот что я придумал для своего конкретного случая. Я решил, что мне просто хотелось бы вернуть всю информацию, чтобы я мог сообщить пользователю о том, что часы особенные.

DECLARE @start DATE = '12-25-2013' 
DECLARE @end DATE = '1-31-2014' 

;WITH [DateIt] AS -- Explodes the dates between start and end inclusive 
(
    SELECT 
     @start AS [sd], 
     DATENAME(dw, @start) AS [dt], 
     DATEPART(dw, @start) AS [dw] 
    UNION ALL 
    SELECT 
     DATEADD(DAY, 1, sd), 
     DATENAME(dw, DATEADD(DAY, 1, sd)) AS [dt], 
     DATEPART(dw, DATEADD(DAY, 1, sd)) AS [dw] 
    FROM 
     [DateIt] [di] 
    WHERE 
     sd < @end 
) 

SELECT --DISTINCT -- May need distinct here 
    [di].[sd] AS [Date], 
    --[di].[dw] AS [DayNumber], 
    --[di].[dt] AS [DayName], 

    [s].[Id] AS [ScheduleId], 
    [s].[Name] AS [ScheduleName], 

    [se].[LocationId], 

    [se].[StartTime], 
    [se].[EndTime], 

    0 AS [ExceptionState] -- Normal Schedule 
FROM 
    [DateIt] [di] 
    INNER JOIN [campusHours].[ScheduleEntries] [se] ON [di].[dw] = [se].[DayId] 
    INNER JOIN [campusHours].[Schedule] [s] ON [s].[Id] = [se].[ScheduleId] 
    --INNER JOIN [campusHours].[ScheduleDates] [sd] ON [sd].[ScheduleId] = [s].[Id] 
WHERE 
    EXISTS 
    (
     SELECT 
      1 
     FROM 
      [campusHours].[ScheduleDates] sd 
     WHERE 
      -- Choose the valid schedule 
      [di].[sd] BETWEEN sd.[StartDate] AND sd.[EndDate] 
      AND 
      -- Don't take days from a different schedule 
      s.[Id] = sd.[ScheduleId] 
    ) 
UNION ALL -- We are going to add in the exceptions 
SELECT 
    [di].[sd] AS [Date], 
    --[di].[dw] AS [DayNumber], 
    --[di].[dt] AS [DayName], 

    0 AS [ScheduleId], -- Represents that we aren't a schedule, could use NULL if you like 
    'Exception' AS [ScheduleName], 

    [e].[LocationId], 

    [e].[StartTime], 
    [e].[EndTime], 

    CASE WHEN [e].[IsContraction] = 1 THEN 1 ELSE 2 END AS [ExceptionState] -- 1 is contraction, 2 is extension 
FROM 
    [DateIt] [di] 
    INNER JOIN [campusHours].[Exception] [e] ON [di].[sd] = [e].[StartDate] 
ORDER BY 
    [di].[sd], [LocationId], [se].[StartTime]