SQL日期/时间操作
所以我有一组特定天数的小时,我们称之为时间表,这个时间表描述了一般模式。然而,偶尔也会有一些我将称之为例外的情况,在这些情况下,时间表会增长或受到限制 例如: 周一的日程安排为上午7:00-下午4:00、下午5:00-9:00 特别是下周一的例外情况:下午6:00-7:00 可以操纵SQL查询中的小时数以返回7:00am-4:00PM、5:00-6:00PM和7:00PM-9:00PM吗。我意识到使用一个临时表和大约三个不同的查询是可能的,但我希望能做得更优雅一些 另一个选择可能是在C逻辑中完成这一切。。。我将非常感谢您对这个日程安排问题的任何帮助 源表请注意,我仍然愿意在必要时更改结构SQL日期/时间操作,sql,sql-server,date,time,schedule,Sql,Sql Server,Date,Time,Schedule,所以我有一组特定天数的小时,我们称之为时间表,这个时间表描述了一般模式。然而,偶尔也会有一些我将称之为例外的情况,在这些情况下,时间表会增长或受到限制 例如: 周一的日程安排为上午7:00-下午4:00、下午5:00-9:00 特别是下周一的例外情况:下午6:00-7:00 可以操纵SQL查询中的小时数以返回7:00am-4:00PM、5:00-6:00PM和7:00PM-9:00PM吗。我意识到使用一个临时表和大约三个不同的查询是可能的,但我希望能做得更优雅一些 另一个选择可能是在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
请把你的建议放在你已经计算过的地方,我们肯定能在这方面做出贡献。我的建议仍然是创建一个proc,使用Getdate函数,创建一个algo来检查这个时间是否属于您的异常。其余的我相信你能猜到。这是我为我的具体案例提出的建议。我决定,我只想收回所有信息,这样我就可以告诉用户一些关于时间的特殊信息
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,则不需要表ScheduleEntries。您已经有了StartDate上的日期是否仅适用于特定的ScheduleEntry?如果是这样,我会在ScheduleEntry表中添加一个Id字段,并在Exception中添加一个对ScheduleId的外键引用。我还将向Exception添加一个DayId字段。然后,您可以将join ScheduleEntries保留在异常上,并将其用作覆盖。看起来CTE集合可能能够处理它。您是否可以编辑您的问题,以包括每列的数据类型以及一些示例输入和结果行?是否要为特定计划或所有计划生成结果?是默认为100的查询提示。如果在查询中指定MAXRECURSION 0,则递归是无限的。