admin

从日期范围内的表中选择所有日期,每个空日期包括1行

sql

我正在尝试重构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

阅读 200

收藏
2021-07-01

共1个答案

admin

有几种处理缺失行的方法,但是所有方法都是关于将另一组数据与您的当前结果结合在一起的。

这可以从您的结果中得出,可以是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很简单,等等。

2021-07-01