在插入DateFrom,DateTo,SatrtTime,EndTime时,需要在MS-SQL中找到重叠记录。
假设我在特定的开始时间和结束时间安排FromDate到EndDate的教师讲课时间。
需要克服以下两个记录重叠的情况
╔═════════════════╦════════════════╦══════════════════╦══════════════════════╦════════════════════╗
║ DateFrom; ║ DateTo; ║ IsFullDay; ║ StartTime; ║ EndTime; ║
║ {Date}; ║ {Date}; ║ {Bit}; ║ {Time(7)}; ║ {Time(7)}; ║
╠═════════════════╬════════════════╬══════════════════╬══════════════════════╬════════════════════╬═══════════════╣
║ 2015-10-10; ║ 2015-10-17; ║ 0; ║ 13:00; ║ 14:45; ║ **Inserted** ║
║ 2015-10-16; ║ 2015-10-18; ║ 0; ║ 14:00; ║ 14:15; ║ **Overlapped**║
║ 2015-10-11; ║ 2015-10-11; ║ 1; ║ 00:00; ║ 00:00; ║ **Overlapped**║
╚═════════════════╩════════════════╩══════════════════╩══════════════════════╩════════════════════╝═══════════════╝
请建议更改MSSQL程序。
答案 0 :(得分:2)
不幸的是,MS SQL没有您需要检查的范围类型。将Start和End作为DateTime值而不是像您一样使用单独的Date和Time值是明智的。假设你将它们改为DateTime:
declare @Start DateTime = '2015/10/16 14:00';
declare @endDate DateTime = '2015/10/18 14:15';
select count(*) from myTable where @endDate > DateFrom and @Start < DateTo;
如果结果不为0则表示您有重叠。
答案 1 :(得分:1)
您可以插入具有重叠条件的选择:
INSERT MyTable (DateFrom, DateTo, IsFullDay, StartTime, EndTime)
SELECT MyDateFrom, MyDateTo, MyIsFullDay, MyStartTime, MyEndTime
FROM MyTable mt
WHERE
NOT EXISTS (SELECT 1 FROM MyTable mt2
WHERE (MyDateTo > mt2.DateFrom and MyDateTo <= mt2.DateTo) or
(mt2.DateTo > MyDateFrom and mt2.DateTo <= MyDateTo))
答案 2 :(得分:1)
(我会添加这个添加评论,但它没有让我把代码放在那里)
然后转换值以将它们作为日期时间(因为你会这么多次,我想你会想把它作为一个函数创建):
SELECT COUNT(*)
FROM myTable
WHERE @endDate > CAST(CONVERT(VARCHAR(10), DateFrom, 111) + ' ' +
CONVERT(VARCHAR(10), StartTime, 114) AS DATETIME) AND
@Start < CAST(CONVERT(VARCHAR(10), DateTo, 111) + ' ' +
CONVERT(VARCHAR(10), EndTime, 114) AS DATETIME);
编辑:BTW我没有在插入的上下文中提供示例,因为如果您正在进行调度应用程序,那么您需要进行各种检查。
答案 3 :(得分:0)
感谢@Cetin Basoz和@Lajos Arpad提出您的建议,我已经尝试过您建议的解决方案,但我可能会犯一些错误来实施。
BTW我的项目架构师允许我添加另一个详细信息表,其中需要每天插入一个开始结束时间,所以我的新时间表就像
主表可用性日期 ╔══════════╦════════════╦═══════════╦═══════════╦═ ════════╦═══════╗
║LectureId║DateFrom║DateTo║IsFullDay║StartTime║EndTime║
║10512║2015-10-14║2015-10-17║1║11:00║11:30║
║10513║2015-10-12║2015-10-14║0║11:00║12:30║
╚══════════╩════════════╩═══════════╩══════════ ═╩═════════╩═══════╝
此处ISFullDay表示全天可用性
详细信息表可用性时间 ╔══════════╦════════════════════╦═════════════════ ══╗
║LectureId║StartDateTime║EndDateTime║
║10512║2015-10-1400:00:00║2015-10-1423:59:59║
║10512║2015-10-1500:00:002015-10-14 23:59:59║
║10512║2015-10-1600:00:00║2015-10-1423:59:59║
║10512║2015-10-1700:00:002015-10-14 23:59:59║
║10513║2015-10-1211:00:00║2015-10-1212:30:00║
║10513║2015-10-1311:00:00║2015-10-1312:30:00║
║10513║2015-10-1411:00:00║2015-10-1412:30:00║
╚══════════╩════════════════════╩══════════════ ═════╝
程序变更如下 DECLARE @DetailDateTime TABLE(StartDate DATETIME,EndDate DATETIME) DECLARE @EndDateTable NVARCHAR(10)= @EndTime
IF(@IsFullDay = 1)
开始
SET @StartTime = '00:00'
SET @ EndDateTable = '00:00'
SET @EndTime = '23:59:59:900' - 当不依赖@IsFullDay时替换此值
结束
--IF(@DateFrom&lt; @DateTo) - 如果From和To Date相同,则时间表中不需要任何值取消注释
开始
; WITH DetailDateTime作为
(
SELECT 1 AS COUNTER,@ DateFrom AS DateFrom,@ DateFrom AS DateTo
UNION ALL
SELECT COUNTER + 1,DATEADD(DAY,COUNTER,@ DateFrom),DATEADD(DAY,COUNTER,@ DateFrom)
来自DetailDateTime
在哪里DATEADD(DAY,COUNTER,@ DateFrom)&lt; = @DateTo
)
INSERT INTO @DetailDateTime SELECT DateFrom + @ StartTime StartTime,DateTo + @ EndTime FROM DetailDateTime
如果(不存在(
选择TOP 1 * FROM
[dbo] .AvailabilityTime A WITH(NOLOCK)
INNER JOIN [dbo] .AvailabilityDates D WITH(NOLOCK)ON A.LectureId = D.LectureId AND ISNULL(D.ISDELETED,0)= 0
INNER JOIN @DetailDateTime B ON(A.StartTime&lt; B.EndDate)AND(B.StartDate&lt; A.EndTime)AND A.AvailabiliyId&lt;&gt; @AvailabiliyId
))
开始
IF(@AvailabiliyId = 0)
开始
INSERT INTO [dbo] .AvailabilityDate ...
结束
其他
BEGIN
更新[dbo] .AvailabilityDate ... WHERE A.AvailabiliyId = @AvailabiliyId
DELETE FROM [dbo] .AvailabilityTime WHERE NonAvailabiliyId = @NonAvailabiliyId
结束
INSERT INTO [dbo] .AvailabilityTime SELECT @ NonAvailabiliyId,* FROM @DetailDateTime
结束
其他
开始
SET @AvailabiliyId = -1 - 重叠冲突
END
非常感谢我花时间陪伴我。 :)
如果在这个解决方案中,请告诉我,我会卡在其他地方