为什么此SQL case语句的行为类似于OR语句?

时间:2018-11-19 23:51:47

标签: sql-server tsql sql-server-2016

考虑以下查询:

declare @RentalId int = 1

SELECT 
     r.RentalId
    ,r.[Name]
    ,rt.TypeId


FROM dbo.Rental r
LEFT JOIN dbo.RentalRateType rt ON (
    r.RentalId = rt.RentalId
    AND rt.TypeId = (
        case when rt.TypeId = 6 and coalesce(rt.[Max], rt.[Min]) is not null then 6
         when rt.TypeId = 1 and coalesce(rt.[Max], rt.[Min] is not null then 1 
        else -1 end
))
WHERE r.RentalId = @RentalId

我正在尝试返回单个记录/行。有问题的特定租金在dbo.RentalRateType表中有2条记录,当我运行上述查询时,我得到2条结果,但是我希望它在case where中的第一个匹配项上短路。 / p>

基本上,最终用户可以填写多种费率类型,比在本示例中看到的更多,并且每种类型都有优先级。示例中的最高优先级是6。

所以我得到了这个结果:

RentalId |   Name   | TypeId
----------------------------
1          Super Car  6    
1          Super Car  1

但是,如果类型(6)存在,我希望仅返回上面的第一行。

我一定很想念一些傻事。可以按预期工作:

case when 1=2 then 6
     when 1=1 then 1 
     else -1 end

虽然我在这里,但我愿意以更有效的方式处理此问题(如果存在)。

1 个答案:

答案 0 :(得分:0)

使用apply代替,这是获取“前n个”查询的有效方法:

SELECT
    r.RentalId
  , r.[Name]
  , oa.TypeId
FROM dbo.Rental r
OUTER APPLY (
        SELECT TOP (1)
            rt.TypeId
        FROM dbo.RentalRateType rt
        WHERE r.RentalId = rt.RentalId
        ORDER BY
            rt.TypeId DESC
    ) oa
WHERE r.RentalId = @RentalId