2013-12-20 2 views
1

그래서 일정이 일반적인 일정을 설명하는 특정 일 집합 (일정이라고 부름)에 대해 시간 집합을가집니다. 그러나 때로는 일정이 커지거나 제한되는 곳에서 예외로 부르는 것이 있습니다.SQL 날짜/시간 조작

예를 들어

: 월요일

일정 7:00 오전 - 오후 4시 오후 5 - 특히 이것에 대한 오후 9시

예외 다음주 월요일 : 오후 6시 - 7:00 PM

오전 7:00 - 오후 4:00, 오후 5:00 - 6:00, 오후 7:00 - 9:00에 SQL 쿼리를 반환하여 시간을 조정할 수 있습니까? . 임시 테이블과 세 가지 다른 쿼리를 사용하는 것이 가능하다는 것을 알았지 만 더 우아하게 처리하기를 바랬습니다.

또 다른 옵션은 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

필드가 날짜 또는 datetime입니까? 귀하의 필드가 datetime 일 경우 ScheduleEntries 테이블이 필요하지 않기 때문에 묻습니다. 시작일에 이미 하루가 있습니다 –

+1

예외는 특정 ScheduleEntry에만 해당됩니까? 그렇다면 Schedule 필드에 Id 필드를 추가하고 Exception에는 ScheduleId에 대한 외래 키 참조를 추가합니다. 또한 DayId 필드를 Exception에 추가합니다. 그런 다음 Exception에서 ScheduleEntries를 왼쪽으로 조인하고 재정의로 사용할 수 있습니다. – 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]