我的任务是在@aircraftId,@ instructorId和@reservationId对可能过滤掉的时间内拉出一些开始时间和结束时间内的记录数量(因此它在计数中忽略了它自己)。所有三个参数都是可空的,因此它们可能会或可能不会被传递,因此查询必须根据它们是否存在进行过滤。我可以使用动态Sql来做到这一点,但我更愿意避免使用它,主要是因为对于任何必须在以后处理它的人来说调试很麻烦。
在单个查询中,这是否可行(我猜它是)?或者,这是其中一种情况,我必须抓住设置,如果它们存在,用其他参数削减它?
SELECT COUNT(*)
FROM AVMAN.Reservation
WHERE ( @aircraftid IS NULL
OR ( @aircraftid IS NOT NULL
AND AircraftId = @aircraftid
)
)
OR ( @InstructorId IS NULL
OR ( @InstructorId IS NOT NULL
AND InstructorUserId = @InstructorId
)
)
AND ( ( -- start during the range
StartTime >= @StartTime
AND StartTime < @EndTime
)
OR ( -- end during the range
EndTime > @StartTime
AND EndTime <= @EndTime
)
OR ( -- start before the range and end after it
StartTime < @StartTime
AND EndTime > @EndTime
)
)
AND ( @ReservationId IS NULL
OR ( ReservationId IS NOT NULL
AND ReservationId = @ReservationId
)
)
答案 0 :(得分:1)
首先,在您的原始SQL中,您有一个OR而不是AND,它会抛弃您的结果。
要整理aircraftId,instructorId和reservationId上的过滤器,您可以执行以下操作:
SELECT COUNT(*)
FROM AVMAN.Reservation
WHERE
ISNULL( @AircraftId, AircraftId ) = AircraftId
AND
ISNULL( @InstructorId, InstructorId ) = InstructorId
AND
ISNULL( @ReservationId, ReservationId ) = ReservationId
AND
( ( -- start during the range
StartTime >= @StartTime
AND StartTime < @EndTime
)
OR ( -- end during the range
EndTime > @StartTime
AND EndTime <= @EndTime
)
OR ( -- start before the range and end after it
StartTime < @StartTime
AND EndTime > @EndTime
)
)
当@AircraftId为空时,ISNULL基本上将AircraftId与@AircraftId进行比较,并将其与AircraftId(显然总是相同)进行比较。
答案 1 :(得分:0)
我不确定但是尝试在WHERE子句中使用CASE,就像这样
SELECT COUNT(*)
FROM AVMAN.Reservation
WHERE CASE
WHEN @aircraftid IS NULL THEN 1
WHEN @aircraftid IS NOT NULL AND AircraftId = @aircraftid THEN 1
END = 1
AND
CASE
WHEN @InstructorId IS NULL THEN 1
WHEN @InstructorId IS NOT NULL AND InstructorUserId = @InstructorId THEN 1
END = 1
AND ( ( -- start during the range
StartTime >= @StartTime
AND StartTime < @EndTime
)
OR ( -- end during the range
EndTime > @StartTime
AND EndTime <= @EndTime
)
OR ( -- start before the range and end after it
StartTime < @StartTime
AND EndTime > @EndTime
)
)
AND
CASE
WHEN @ReservationId IS NULL THEN 1
WHEN ReservationId IS NOT NULL AND ReservationId = @ReservationId THEN 1
END = 1