我正在尝试重构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
答案 0 :(得分:3)
有几种方法可以处理丢失的行,但所有这些方法都是为了让另一组数据与当前结果相结合。
这可能来自您的结果,由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
这会将日历模板放在LEFT上,因此您可以更轻松地查询许多查询,因为您知道日历的日期字段始终填充,始终是仅日期(无时间部分)值,是订单,对GROUP BY等很简单
答案 1 :(得分:0)
嗯,想法是一样的,但我会编写函数,返回包含句点中所有日期的表。看看这个:
Create Function [dbo].[Interval]
(
@DateFrom Date,
@DateTo Date
)
Returns @tab Table
(
MyDate DateTime
)
As
Begin
Declare @Days int
Declare @i int
Set @Days = DateDiff(Day, @DateFrom, @DateTo)
Set @i = 0;
While (@Days > @i)
Begin
Insert Into @tab(MyDate)
Values (DateAdd(Day, @i, @DateTo))
Set @i = @i + 1
End
return
End
并在需要时重复使用该功能..
Select *
From [dbo].[Interval]('2011-01-01', GETDATE())