在SQL Server条件WHERE子句

问题描述 投票:56回答:5

我创造,我需要一个条件where子句的SQL查询。

它应该是这样的:

SELECT 
    DateAppr,
    TimeAppr,
    TAT,
    LaserLTR,
    Permit,
    LtrPrinter,
    JobName,
    JobNumber,
    JobDesc,
    ActQty,
    (ActQty-LtrPrinted) AS L,
    (ActQty-QtyInserted) AS M,
    ((ActQty-LtrPrinted)-(ActQty-QtyInserted)) AS N
FROM 
    [test].[dbo].[MM]
WHERE 
    DateDropped = 0
            --This is where i need the conditional clause 
    AND CASE
            WHEN @JobsOnHold = 1 THEN DateAppr >=  0
            ELSE  DateAppr != 0
        END

上面的查询是行不通的。这是不正确的语法或有另一种方式来做到这一点,我不知道吗?

我不想使用动态SQL,那么有没有任何其他方式或做我必须使用像使用if else并使用不同where子句相同的查询解决方法?

sql sql-server sql-server-2008 tsql where-clause
5个回答
72
投票

尝试这个

SELECT 
    DateAppr,
    TimeAppr,
    TAT,
    LaserLTR,
    Permit,
    LtrPrinter,
    JobName,
    JobNumber,
    JobDesc,
    ActQty,
    (ActQty-LtrPrinted) AS L,
    (ActQty-QtyInserted) AS M,
    ((ActQty-LtrPrinted)-(ActQty-QtyInserted)) AS N
FROM 
    [test].[dbo].[MM]
WHERE 
    DateDropped = 0
    AND (
    (ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0) 
    OR 
    (ISNULL(@JobsOnHold, 0) != 1 AND DateAppr != 0)
    )

You can read more about conditional WHERE here.


25
投票

试试这个 -

WHERE DateDropped = 0
    AND (
        (ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0) 
        OR 
        (ISNULL(@JobsOnHold, 0) != 1 AND DateAppr != 0)
    )

11
投票

要回答如何在WHERE子句中使用CASE表达式的基本问题:

首先记住,CASE表达式的值必须有一个正常的数据类型值,而不是一个布尔值。它必须是一个VARCHAR,或一个int,或什么的。这是你不能说SELECT Name, 76 = Age FROM [...],并期望得到'Frank', FALSE结果集一样的道理。

此外,在WHERE子句中的所有表达式需要有一个布尔值。他们不能有一个varchar或int值。你不能说WHERE Name;WHERE 'Frank';。你必须使用一个比较操作,使之成为布尔表达式,所以WHERE Name = 'Frank';

这意味着,CASE表达式必须是一个布尔表达式的一侧。你必须CASE表达式比较的东西。它不能自立!

这里:

WHERE 
    DateDropped = 0
    AND CASE
            WHEN @JobsOnHold  = 1 AND DateAppr >= 0 THEN 'True'
            WHEN DateAppr != 0 THEN 'True'
            ELSE 'False'
        END = 'True'

请注意,在端部左侧的CASE表达会变成布尔表达式为任一'True' = 'True''False' = 'True'

请注意,有没有什么特别的'False''True'。您可以使用0,如果你宁愿1了。

您通常可以重写CASE表达式为布尔表达式我们已经比较熟悉了,而这通常获得更好的性能。然而,有时更容易或更容易维护比它到逻辑转换为使用现有的表达。


7
投票

您查询的问题是,在CASE表达式中,THENELSE部件必须有一个计算结果为数字或VARCHAR或任何其它数据类型而不是一个布尔值的表达式。

你只需要使用布尔逻辑(或者更确切地说是SQL使用三元逻辑)和重写它:

WHERE 
    DateDropped = 0
AND ( @JobsOnHold = 1 AND DateAppr >= 0 
   OR (@JobsOnHold <> 1 OR @JobsOnHold IS NULL) AND DateAppr <> 0
    )

0
投票

通常,当您使用条件WHERE子句,你最终UPP一个大大低效的查询,这是明显的,其中索引用于大型数据集。以优化您的参数的不同值的查询一个伟大的方式就是让不同的执行计划参数的每个值。您可以使用OPTION (RECOMPILE)实现这一目标。

在这个例子中它可能没有太大的差别,但说的情况应该只在两个中的一个情况下才能使用,那么你可以看到有很大的影响。

在这个例子:

WHERE 
    DateDropped = 0
    AND (
    (ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0) 
    OR 
    (ISNULL(@JobsOnHold, 0) <> 1 AND DateAppr <> 0)
    )
OPTION (RECOMPILE)

来源Parameter Sniffing, Embedding, and the RECOMPILE Options

© www.soinside.com 2019 - 2024. All rights reserved.