我很惊讶这还没有出现。
在T-SQL中,我需要找到与每日间隔重叠的间隔(由startDateTime和endDateTime定义)(例如,上午9点至下午5点)。
例如,使用表格:
CREATE TABLE [dbo].[Interval](
[startDateTime] [datetime] NOT NULL,
[endDateTime] [datetime] NOT NULL
)
解决方案是只返回重叠间隔的过程:
CREATE PROCEDURE FindIntervals
-- Add the parameters for the stored procedure here
@from varchar(5) = '9:00',
@to varchar(5) = '17:00'
AS
BEGIN
select * from Interval
where ...
END
GO
编辑: 示例区间:
因此,对于给定的间隔“九到五”,应该返回2,3,5和6,因为它们与给定的输入重叠。
但是,
也适合,因为它包括整天。
请帮助我在T-SQL中匹配字符串和日期时间值,而不是抽象的“少于”/“大于”的解决方案。
答案 0 :(得分:4)
declare @Interval table
(
startDateTime datetime,
endDateTime datetime
)
insert into @Interval values
('2011-09-07T08:00:00', '2011-09-07T08:30:00'),
('2011-09-07T11:00:00', '2011-09-07T13:00:00'),
('2011-09-07T13:00:00', '2011-09-07T18:00:00'),
('2011-09-09T08:00:00', '2011-09-09T08:30:00'),
('2011-09-09T11:00:00', '2011-09-09T13:00:00'),
('2011-09-09T13:00:00', '2011-09-09T18:00:00'),
('2011-09-09T08:00:00', '2011-09-10T08:30:00')
declare @from varchar(5) = '09:00'
declare @to varchar(5) = '17:00'
;with L(MinDate, MaxDate) as
(
select dateadd(day, datediff(day, 0, min(startDateTime)), 0),
dateadd(day, datediff(day, 0, max(endDateTime)), 0)
from @Interval
),
D(fromTime, endTime) as
(
select dateadd(day, Number.number, L.MinDate)+cast(@from as datetime),
dateadd(day, Number.number, L.MinDate)+cast(@to as datetime)
from L
inner join master..spt_values as Number
on Number.number <= datediff(day, L.MinDate, L.MaxDate)
where Number.type = 'P'
)
select I.startDateTime,
I.endDateTime
from @Interval as I
where exists (select *
from D
where I.startDateTime < D.endTime and
I.endDateTime > D.fromTime)
结果:
startDateTime endDateTime
----------------------- -----------------------
2011-09-07 11:00:00.000 2011-09-07 13:00:00.000
2011-09-07 13:00:00.000 2011-09-07 18:00:00.000
2011-09-09 11:00:00.000 2011-09-09 13:00:00.000
2011-09-09 13:00:00.000 2011-09-09 18:00:00.000
2011-09-09 08:00:00.000 2011-09-10 08:30:00.000
如果您希望日期范围超过2048天,则需要使用数字表替换master..spt_values。确保数字表以0
开头。
SQL Server 2008版本
;with L(MinDate, MaxDate) as
(
select cast(min(startDateTime) as date),
cast(max(endDateTime) as date)
from @Interval
),
D(fromTime, endTime) as
(
select dateadd(day, Number.number, L.MinDate)+cast(@from as datetime),
dateadd(day, Number.number, L.MinDate)+cast(@to as datetime)
from L
inner join master..spt_values as Number
on Number.number <= datediff(day, L.MinDate, L.MaxDate)
where Number.type = 'P'
)
select I.startDateTime,
I.endDateTime
from @Interval as I
where exists (select *
from D
where I.startDateTime < D.endTime and
I.endDateTime > D.fromTime)