여기에 제가 생각한 구체적인 사례를 생각해 보았습니다. 사용자에게 시간대에 대해 특별한 정보를 제공 할 수 있도록 모든 정보를 다시 제공하기로 결정했습니다.
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]
소스 테이블을 설명하십시오. –
필드가 날짜 또는 datetime입니까? 귀하의 필드가 datetime 일 경우 ScheduleEntries 테이블이 필요하지 않기 때문에 묻습니다. 시작일에 이미 하루가 있습니다 –
예외는 특정 ScheduleEntry에만 해당됩니까? 그렇다면 Schedule 필드에 Id 필드를 추가하고 Exception에는 ScheduleId에 대한 외래 키 참조를 추가합니다. 또한 DayId 필드를 Exception에 추가합니다. 그런 다음 Exception에서 ScheduleEntries를 왼쪽으로 조인하고 재정의로 사용할 수 있습니다. – Jordan