SQL 在 WHERE IN 子句中使用 CASE 语句
Posted
技术标签:
【中文标题】SQL 在 WHERE IN 子句中使用 CASE 语句【英文标题】:SQL use CASE statement in WHERE IN clause 【发布时间】:2013-10-16 19:14:18 【问题描述】:是否可以在 where in 子句中使用 case ? 像这样的:
DECLARE @Status VARCHAR(50);
SET @Status='published';
SELECT * FROM Product P
WHERE P.Status IN (CASE WHEN @Status='published' THEN (1,3)
WHEN @Status='standby' THEN (2,5,9,6)
WHEN @Status='deleted' THEN (4,5,8,10)
ELSE (1,3)
END)
此代码给出错误:',' 附近的语法不正确。
【问题讨论】:
P.Status 的类型是什么? 您可以在where
中使用case
,但不能这样。 Case
每条语句必须返回一个值。
@MaryamArshi:P.Status 的类型是 int。
@SeanCoetzee。我不明白。可以举个例子吗?
只是问,THEN(2,5,9,6) 有什么意义?
【参考方案1】:
根据我的场景,我确实“在 WHERE IN 子句中使用 CASE 语句”,如下所示
@AdjType varchar(20) = 'Value',
@Base varchar(20) = 'Common'
where
(select CASE WHEN SA.IsPersentage = 0 THEN 'Value'
WHEN SA.IsPersentage = 1 THEN 'Presentage' END) Like @AdjType
and (Select CASE WHEN SA.IsDependOnBasicSalary = 0 THEN 'Common'
WHEN SA.IsDependOnBasicSalary = 1 THEN 'Basic Salary' END) like @Base
【讨论】:
【参考方案2】: SELECT * FROM Tran_LibraryBooksTrans LBT
LEFT JOIN Tran_LibraryIssuedBooks LIB ON
CASE WHEN LBT.IssuedTo='SN' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1
WHEN LBT.IssuedTo='SM' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1
WHEN LBT.IssuedTo='BO' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1
ELSE 0 END
【讨论】:
【参考方案3】:我相信你可以在 where 子句中使用 case 语句,我是这样做的:
Select
ProductID
OrderNo,
OrderType,
OrderLineNo
From Order_Detail
Where ProductID in (
Select Case when (@Varibale1 != '')
then (Select ProductID from Product P Where .......)
Else (Select ProductID from Product)
End as ProductID
)
这种方法一次又一次地对我有用。试试看!
【讨论】:
它对我有用,创建了一个临时表,根据参数条件插入所需的产品并加入临时表,最后删除了临时表【参考方案4】:也许你可以试试这个方法
SELECT *
FROM Product P
WHERE (CASE
WHEN @Status = 'published' THEN
(CASE
WHEN P.Status IN (1, 3) THEN
'TRUE'
ELSE
FALSE
END)
WHEN @Status = 'standby' THEN
(CASE
WHEN P.Status IN (2, 5, 9, 6) THEN
'TRUE'
ELSE
'FALSE'
END)
WHEN @Status = 'deleted' THEN
(CASE
WHEN P.Status IN (4, 5, 8, 10) THEN
'TRUE'
ELSE
'FALSE'
END)
ELSE
(CASE
WHEN P.Status IN (1, 3) THEN
'TRUE'
ELSE
'FALSE'
END)
END) = 'TRUE'
这样,如果@Status = 'published',查询将检查P.Status 是否在1 或3 之间,否则返回TRUE,否则返回'FALSE'。这将在最后与 TRUE 匹配
希望对你有帮助。
【讨论】:
【参考方案5】:不,您不能像这样使用case
和in
。但是你可以做
SELECT * FROM Product P
WHERE @Status='published' and P.Status IN (1,3)
or @Status='standby' and P.Status IN (2,5,9,6)
or @Status='deleted' and P.Status IN (4,5,8,10)
or P.Status IN (1,3)
顺便说一句,您可以将其减少到
SELECT * FROM Product P
WHERE @Status='standby' and P.Status IN (2,5,9,6)
or @Status='deleted' and P.Status IN (4,5,8,10)
or P.Status IN (1,3)
因为or P.Status IN (1,3)
还提供了@Status='published' and P.Status IN (1,3)
的所有记录
【讨论】:
您不需要在每个“或”子句周围加上括号吗?例如。或(@Status='standby' 和 P.Status IN (2,5,9,6)) 不要认为你需要括号,但最后一个or
语句会返回错误的结果......看这个小提琴——不应该返回第二条记录。 sqlfiddle.com/#!3/9aef0/6
AND 的优先级高于 OR。这就是在这种情况下不需要括号的原因。【参考方案6】:
select * from Tran_LibraryBooksTrans LBT left join
Tran_LibraryIssuedBooks LIB ON case WHEN LBT.IssuedTo='SN' AND
LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1 when LBT.IssuedTo='SM'
AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1 WHEN
LBT.IssuedTo='BO' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1
ELSE 0 END`enter code here`select * from Tran_LibraryBooksTrans LBT
left join Tran_LibraryIssuedBooks LIB ON case WHEN LBT.IssuedTo='SN'
AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1 when
LBT.IssuedTo='SM' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1
WHEN LBT.IssuedTo='BO' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN
1 ELSE 0 END
【讨论】:
【参考方案7】:我知道这个问题已经得到解答,但是接受的解决方案存在一个小问题。它将返回误报。易于修复:
SELECT * FROM Products P
WHERE (@Status='published' and P.Status IN (1,3))
or (@Status='standby' and P.Status IN (2,5,9,6))
or (@Status='deleted' and P.Status IN (4,5,8,10))
or (@Status not in ('published','standby','deleted') and P.Status IN (1,2))
SQL Fiddle Demo
不需要括号(尽管可能更容易阅读,因此我将它们包括在内)。
【讨论】:
以上是关于SQL 在 WHERE IN 子句中使用 CASE 语句的主要内容,如果未能解决你的问题,请参考以下文章
在 where 子句 SQL 中的 case 语句中使用参数
如何在 SQL Server 的 Where 子句中使用 case 语句