我需要根据参数'@HotList'选择行。
当"@HotList"="是"时,我需要拉出"co.ro_HotList"字段包含"是"值的所有行 当"@HotList"="否"时,我需要拉取"co.ro_HotList"字段包含"否"或 null 值的所有行
我可以仅根据参数选择值为"是"或"否"的行,但无法弄清楚当参数为"否"时如何选择空行。如何修改提供的代码来实现此目的?
我尝试在 where 子句中使用案例语句,但没有运气。
SELECT ds.*
FROM Rotex_DailyShipmentNotShip ds
left outer join CRM_MSCRM..SalesOrder co ON ds.SOP#=co.Name
WHERE co.ro_HotList = @HotList
在以下位置尝试此操作:
ISNULL(co.ro_HotList,'No') = @HotList
ISNULL 将评估第二个输入的空值,因此在您的情况下,所有空值都被视为"否"。
Keith的答案是正确的,但为了完整起见,您提到您尝试CASE
,这就是应该如何使用CASE
来完成。
WHERE CASE WHEN co.ro_HotList IS NULL
THEN 'No'
ELSE co.ro_HotList
END = @HotList
您可以编写过滤条件,如下所示:
SELECT ds.*
FROM Rotex_DailyShipmentNotShip ds
left outer join CRM_MSCRM..SalesOrder co ON ds.SOP#=co.Name
WHERE @HotList = 'Yes' and co.ro_HotList = 'Yes'
OR @HotList = 'No' and (co.ro_HotList = 'No' or co.ro_HotList is null)
OP 问题的几个答案是有效的,因为它们返回预期的结果,但其中大多数是低效的,因为它们会阻止正确的索引使用。
将列名括在大小写表达式或函数等表达式中可防止 SQL Server 使用索引。
具有 OR 运算符和参数条件的谓词也会阻止有效的执行计划。
有几种方法可以有效地构造查询:
添加计算列
添加计算列,例如:
更改表将热列表添加为为空(ro_HotList,"否")
并为其编制索引。然后,查询将更简单且索引友好:
其中热列表 = @HotList
智能客户端应用程序
客户端应用程序可能足够智能,可以执行以下操作(伪代码)
If HostListParameter is "No" then execute the query:
SELECT <column list>
FROM Whatever
WHERE ro_HostList = 'No' OR ro_HostList IS NULL
Else execute this other query:
SELECT <column list>
FROM Whatever
WHERE ro_HostList = @HotList
Invalid parameter
将 T-SQL 批处理与逻辑结合使用
不是执行单个选择语句,而是使用逻辑执行批处理
IF @HostList = 'No'
BEGIN
SELECT <column list>
FROM Whatever
WHERE ro_HostList = 'No' OR ro_HostList IS NULL
END
ELSE
BEGIN
SELECT <column list>
FROM Whatever
WHERE ro_HostList = @HotList
END
使用存储过程
可以创建执行与前面的 T-SQL 批处理相同的逻辑的存储过程
使用OPTION(RECOMPILE)
添加选项(重新编译)
将 OPTION(重新编译)添加到 Impaler 答案会导致可以使用索引的更好的执行计划,但它也会阻止计划重用。
但很少使用低选择性非覆盖指数
如果一列包含的值很少,则非覆盖索引大多是无用的。
在这种情况下,我认为该列只能包含"是"、"否"或 NULL。因此,将其编入索引不会提高性能。最好的答案是KeithL的。