SQL Server If 条件在 where 子句?

Posted

技术标签:

【中文标题】SQL Server If 条件在 where 子句?【英文标题】:SQL Server If condition at where clause? 【发布时间】:2016-01-21 15:36:20 【问题描述】:

我想做一个选择查询,我有几个参数,但根据值我将参数添加到 where 子句。我不想使用动态查询。 例如这是我存储的声明:

EXEC GETProducts @ProductID INT = -1, @ProductName NVARCHAR(100) = NULL, @ProductManufacturerID INT = -1

我想要ManufacturerID = 3生产的所有产品

EXEC GETProducts -1, NULL, 3

我想要这样的查询,我知道它不起作用,我也尝试使用 CASE,但不起作用。

SELECT * FROM Product
WHERE 
IF(@ProductID > -1)
BEGIN
 ProductID = @ProductID
END
AND
IF(@ProductName <> '')
BEGIN
 ProductName = @ProductName 
END
AND
IF(@ProductManufacturerID > -1)
BEGIN
 ProductManufacturerID = @ProductManufacturerID 
END

感谢您的帮助!!!

【问题讨论】:

显示您对CASE 的尝试,因为这将比IF 更接近有效的解决方案。 另外,如果您可以尝试展示您的开始以及您的输出和预期输出是什么。 在这种情况下,case 语句似乎比 IF 语句更合理,因为您的代码可能会变得非常混乱 Dynamic Search Conditions in T-SQL by Erland Sommarskog 涵盖了很多选项 @MarkHill IF 完全无效,因为它用于程序流,而不是表达式评估,并且不能在 WHERE 子句中使用。 【参考方案1】:

听起来您想要ANDs 和ORs 的组合,而不是CASEIF

SELECT * FROM Product
WHERE 
(@ProductID <= -1 OR ProductID = @ProductID)
AND
(@ProductName = '' OR ProductName = @ProductName)
AND
(@ProductManufacturerID <= -1 OR ProductManufacturerID = @ProductManufacturerID)

但是我会注意到NULL通常在特殊情况下优于“魔术”数字和字符串:

SELECT * FROM Product
WHERE 
(@ProductID IS NULL OR ProductID = @ProductID)
AND
(@ProductName IS NULL OR ProductName = @ProductName)
AND
(@ProductManufacturerID IS NULL OR ProductManufacturerID = @ProductManufacturerID)

【讨论】:

使用OR,他不会选择两个条件之一满足的情况吗?假设@PruductID 为 -3,ProductID 为 5。由于子句 (@ProductID @BlackAdder 正确。意图很可能使用任何负数作为“幻数”来选择所有产品(有效地不按产品 ID 过滤)。我猜在这种情况下,但这是一个常见的用例。【参考方案2】:
SELECT * 
FROM Product
WHERE 
    (@ProductID = -1 OR ProductID = @ProductID)
AND (@ProductName = '' OR ProductName = @ProductName)
AND (@ProductManufacturerID = -1 OR ProductManufacturerID = @ProductManufacturerID)

【讨论】:

【参考方案3】:

我在这里猜测了一下。你可能想写:

WHERE 
(@ProductID > -1 AND ProductID = @ProductID)
OR
(@ProductName <> '' AND ProductName = @ProductName )
OR
(@ProductManufacturerID > -1 AND ProductManufacturerID = @ProductManufacturerID)

【讨论】:

【参考方案4】:

您可以通过将OR 子句与OR 子句配对来制作“有条件的”WHERE 子句。像这样的:

SELECT * FROM Product
WHERE
    (@ProductID <= -1 OR ProductID = @ProductID)
    AND @ProductName = '' OR ProductName = @ProductName)
    -- etc.

这样,如果“条件检查”为真,则不会评估 OR 子句的后半部分。

【讨论】:

【参考方案5】:

您可以通过将条件设为复合条件来将查询更改为如下所示,并且您不需要CASE 表达式。顺便说一句,IF .. ELSE 构造仅在程序主体内有效。

SELECT * FROM Product
WHERE (@ProductID > -1 AND ProductID = @ProductID)
AND (@ProductName <> '' AND ProductName = @ProductName)
AND (@ProductManufacturerID > -1 AND ProductManufacturerID = @ProductManufacturerID)

【讨论】:

【参考方案6】:

您可以将条件句转换为 WHERE 子句中的要求。

IF(@ProductID > -1)
BEGIN
    ProductID = @ProductID
END

相当于:

ProductID > -1 AND ProductID = @ProductID

,

IF(@ProductName <> '')
BEGIN
    ProductName = @ProductName 
END

相当于:

ProductName <> '' AND ProductName = @ProductName

,

IF(@ProductManufacturerID > -1)
BEGIN
    ProductManufacturerID = @ProductManufacturerID 
END

相当于:

ProductManufacturerID > -1 AND ProductManufacturerID = @ProductManufacturerID 

所以你的最终查询将是:

SELECT * FROM Product WHERE 
ProductID > -1 AND
ProductID = @ProductID AND
ProductName <> '' AND
ProductName = @ProductName AND
ProductManufacturerID > -1 AND
ProductManufacturerID = @ProductManufacturerID 

【讨论】:

您的“等价物”不正确 - 例如如果@ProductID 小于-1,则ProductID 上将没有过滤器。如果 @ProductID 小于 -1,您的等价物将删除所有记录。 我误解了@user2112420 想要实现的目标。在我看来,他似乎想首先检查产品的 ID > -1,然后检查它是否对应于变量中的 ID。【参考方案7】:

当您的参数旨在影响 select 查询时,case 将评估为 1,因此使其成为 select 语句的一部分,如果不是,它将为 0,因此它不会计数,因为 0=1 将评估为 false。

SELECT * FROM Product
WHERE 
(CASE 
     WHEN @ProductId > -1 AND ProductId = @ProductId THEN 1 
     ELSE 0
 END) = 1
AND 
(CASE 
     WHEN @ProductName <> '' AND ProductName = @ProductName THEN 1 
     ELSE 0
END) = 1
AND 
(CASE
     WHEN @ProductManufacturerID > -1 AND ProductManufacturerID = @ProductManufacturerID THEN 1 
END);

【讨论】:

将@parameter 与行值进行比较时遗漏了部分 @JuanCarlosOropeza 编辑了我的答案,现在应该没问题了。

以上是关于SQL Server If 条件在 where 子句?的主要内容,如果未能解决你的问题,请参考以下文章

ms sql server中where子句中的if else条件

简述SELECT语句中的FROM、WHERE以及ORDER BY子句的作用。SQL Server

关于sql语句添加where条件问题,用java语句

where条件放在子SQL语句中是否查询速度更快?

sql语句中where条件的嵌套子查询性能

sql中where 之后怎么加if条件判断