在where子句中使用CASE - 带参数

时间:2015-10-16 00:33:14

标签: sql sql-server tsql

我正在寻找一个使用变量在where子句中的case语句的好例子。变量返回的数字决定了where子句的结果。我的查询如下:

IF          @RequestType = 99
    SELECT  @Received = count(*)
    FROM    Request r
    WHERE   request_received_date between @beginDate and @endDate
    AND     request_type_id <> 5
    ELSE IF @RequestType = 100
BEGIN
    SELECT  @Received = count(*)
    FROM    Request r
    WHERE   request_received_date between @beginDate and @endDate
END
    ELSE
BEGIN
    SELECT  @Received = count(*)
    FROM    Request r
    WHERE   request_received_date between @beginDate and @endDate
    AND     request_type_id = 
            (CASE WHEN @RequestType = 1 THEN (1)
            WHEN @RequestType = 2 THEN (2)
            WHEN @RequestType = 3 THEN (3)
            WHEN @RequestType = 4 THEN (4)
            WHEN @RequestType = 5 THEN (5)
            END)
END

正如您所看到的,有7个选项 - 客户希望灵活处理他们在报告中看到的数据量。这对我来说看起来很麻烦,但我想不出有任何其他方法可以做到这一点。

2 个答案:

答案 0 :(得分:0)

您可以将查询简化为...

(5,6)

最后一种情况/当组件与请求类型匹配时,获取的值低于6以匹配请求类型的值。如果您有负片,那么只需相应调整。

我修改了查询,使其有一个预先查询“PV”,表示您要查找的参数值,因此可以根据需要将它们更改为任何请求类型和日期范围。这应该适用于SQL-Server,也可能适用于其他SQL引擎。通过仅对没有“FROM”的硬值进行查询,它实际上创建了单个记录的结果集,其中这些值可以用于查询的其余部分。任何一个单独的记录,任何笛卡尔联合都没有问题。

答案 1 :(得分:0)

在WHERE子句中通常不需要CASE WHEN,因为你有AND和OR。您的查询转换为:

select @Received = count(*)
from request
where request_received_date between @beginDate and @endDate
and 
(
  @RequestType = 100
    or
  (@RequestType = 99 and request_type_id <> 5)
    or
  (@RequestType = request_type_id and request_type_id in (1,2,3,4,5))
);