59 sql t-sql sql-server where-clause sql-server-2008
我正在创建一个SQL查询,我需要一个条件where子句.
它应该是这样的:
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
Run Code Online (Sandbox Code Playgroud)
以上查询无效.这不是正确的语法,还是有其他方法可以做到这一点,我不知道?
我不想使用动态SQL,所以有没有其他方法或我必须使用一个解决方法,如使用if else和使用不同的where子句相同的查询?
Mah*_*esh 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)
)
Run Code Online (Sandbox Code Playgroud)
Dev*_*art 25
试试这个 -
WHERE DateDropped = 0
AND (
(ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0)
OR
(ISNULL(@JobsOnHold, 0) != 1 AND DateAppr != 0)
)
Run Code Online (Sandbox Code Playgroud)
Bac*_*its 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'
Run Code Online (Sandbox Code Playgroud)
请注意,左边的CASE表达式如何将布尔表达式转换为'True' = 'True'或者'False' = 'True'.
请注意,有没有什么特别的'False'和'True'.你可以使用0,1如果你也愿意.
您通常可以将CASE表达式重写为我们更熟悉的布尔表达式,这通常对性能更好.但是,使用现有表达式有时比转换逻辑更容易或更易于维护.
您的查询的问题在于,在CASE表达式中,THEN和ELSE部分必须具有一个表达式,该表达式的计算结果为数字或varchar或任何其他数据类型,但不是布尔值.
您只需要使用布尔逻辑(或者更确切地说是SQL使用的三元逻辑)并重写它:
WHERE
DateDropped = 0
AND ( @JobsOnHold = 1 AND DateAppr >= 0
OR (@JobsOnHold <> 1 OR @JobsOnHold IS NULL) AND DateAppr <> 0
)
Run Code Online (Sandbox Code Playgroud)
通常,当您使用条件 WHERE 子句时,您最终会得到效率极低的查询,这对于使用索引的大型数据集来说非常明显。针对参数的不同值优化查询的一个好方法是为参数的每个值制定不同的执行计划。您可以使用 来实现这一点OPTION (RECOMPILE)。
在此示例中,它可能不会产生太大差异,但假设该条件仅应在两种情况之一中使用,那么您可能会注意到很大的影响。
在这个例子中:
WHERE
DateDropped = 0
AND (
(ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0)
OR
(ISNULL(@JobsOnHold, 0) <> 1 AND DateAppr <> 0)
)
OPTION (RECOMPILE)
Run Code Online (Sandbox Code Playgroud)