我正在尝试重构ASP.Net网站中的某些代码,并且正在编写的存储过程有问题。
我想做的是获取一个日期范围,然后从表格中选择该范围内的所有数据,但如果不存在日期,我仍然需要选择一行。
正如您在下面的代码中看到的那样,我的想法是创建一个临时表,并用日期范围内的所有日期填充该表,然后将其加入到我要选择的表中,但这是行不通的。我在这里做错什么了吗?tempDate列在此联接中始终为null,但是我已经检查了表,并且表中确实有数据。
-- Parameters DECLARE @DutyDate datetime='2012-01-01 00:00:00' DECLARE @InstructorID nvarchar(2) = N'29' DECLARE @datesTBL TABLE (tempDate DATETIME) -- Variables DECLARE @StartDate DATETIME DECLARE @EndDate DATETIME SELECT @StartDate =StartDate, @EndDate = EndDate FROM DutyPeriodTbl WHERE (StartDate <= @DutyDate) AND (EndDate >= @DutyDate) DECLARE @d DATETIME = @StartDate WHILE @d<=@EndDate BEGIN INSERT INTO @datesTBL VALUES (CONVERT(DATETIME, @d, 102)) SET @d=DATEADD(day,1,@d) END SELECT dt.tempDate , InstructorID, EventStart, EventEnd, cancelled, cancelledInstructor, EventType, DevName, Room, SimLocation, ClassLocation, Event, Duration, TrainingDesc, Crew, Notes, LastAmended, InstLastAmended, ChangeAcknowledged, Type, OtherType, OtherTypeDesc, CourseType FROM OpsInstructorEventsView iv LEFT OUTER JOIN @datesTBL dt ON CONVERT(DATETIME, iv.EventStart, 102) = CONVERT(DATETIME, dt.tempDate, 102) WHERE InstructorID = @InstructorID AND EventStart BETWEEN CONVERT(DATETIME, @StartDate, 102) AND CONVERT(DATETIME, @EndDate, 102) ORDER BY EventStart
有几种处理缺失行的方法,但是所有方法都是关于将另一组数据与您的当前结果结合在一起的。
这可以从您的结果中得出,可以是CTE或其他过程(例如您的示例)创建的结果,也可以是(使用我的偏好)通过使用永久 模板 进行加入而得出的结果。
您的情况下的模板可能只是一个日期表,例如您的@datesTBL。区别在于它是预先创建的,例如,具有100年的日期。
您的查询可能类似于您的示例,但是我会尝试以下操作…
SELECT dt.tempDate , InstructorID, EventStart, EventEnd, cancelled, cancelledInstructor, EventType, DevName, Room, SimLocation, ClassLocation, Event, Duration, TrainingDesc, Crew, Notes, LastAmended, InstLastAmended, ChangeAcknowledged, Type, OtherType, OtherTypeDesc, CourseType FROM @datesTBL dt LEFT OUTER JOIN OpsInstructorEventsView iv ON iv.EventStart >= dt.tempDate AND iv.EventStart < dt.tempDate + 1 AND iv.InstructorID = @InstructorID WHERE dt.tempDate >= @StartDate AND dt.tempDate <= @EndDate ORDER BY dt.tempDate, iv.EventStart
这将 日历模板 放在左侧,因此您可以轻松地进行许多查询,因为您知道日历的日期字段总是填充,始终是仅日期(无时间部分)值,有序,对于GROUP BY很简单,等等。