SQL Server不支持在CASE语句中使用OR。

605

CASE语句中的WHEN子句不支持OR运算符。我该怎么做?

CASE ebv.db_no 
    WHEN 22978 OR 23218 OR 23219 THEN 'WECS 9500' 
    ELSE 'WECS 9520' 
END as wecs_system 

SQL标准允许多个值:https://dev59.com/dms05IYBdhLWcg3wGuKd#54562580 - Lukasz Szozda
11个回答

1115

那个格式要求你使用以下之一:

CASE ebv.db_no 
  WHEN 22978 THEN 'WECS 9500' 
  WHEN 23218 THEN 'WECS 9500'  
  WHEN 23219 THEN 'WECS 9500' 
  ELSE 'WECS 9520' 
END as wecs_system 
否则,请使用:
CASE  
  WHEN ebv.db_no IN (22978, 23218, 23219) THEN 'WECS 9500' 
  ELSE 'WECS 9520' 
END as wecs_system 

9
第二种情况为什么只能使用“IN”,而不能使用“=”? - Han
27
如果你要与单个值进行比较,= 操作符是可行的。然而,(22978, 23218, 23219) 是一个数组,需要使用 IN 操作符来匹配其中的一个值。 - LdTrigger
2
这真的很糟糕 - T-SQL 无法处理 case 语句中的 "or"。微软,是时候从玩具数据库状态中成长了。 - Rich Bianco
2
无法在case语句中处理“or”...嗯...我想我从未见过任何语言的switch接受“or”。这似乎违背了switch的目的。哪些语言接受case中的“or”? - Heriberto Lugo
2
@Heriberto Lugo,我不知道你懂多少种语言,但至少有几种。VB.NET和C#可以通过简单的逗号分隔符来使用它们。这并没有什么不好,因为它可以避免你在多个情况下重复编写相同的代码。 - Johnny Prescott
显示剩余6条评论

270
CASE
  WHEN ebv.db_no = 22978 OR 
       ebv.db_no = 23218 OR
       ebv.db_no = 23219
  THEN 'WECS 9500' 
  ELSE 'WECS 9520' 
END as wecs_system 

40
点赞 - 这个回答确实增加了价值。它更贴近问题的本意,如果你想嵌套一些CASE-WHEN,这种语法可以显著减少所需代码。 - Matt Kemp
1
@Leigh,非常感谢您的回答。将所有不同格式放在一个帖子中,使其更易于作为参考使用。 - Jason Wheeler
3
@Bigwheels - 哇,这是一段时间之前的事了。我可能不同意,因为从逻辑上讲,它与 其他回答 完全相同。话虽如此,你和马特提出了有效的观点。如果问题是“仅使用 OR 的正确语法是什么”,则这提供了一个答案。然而,如果“减少必要的语法”是目标,则被接受的回答 更加紧凑。顺便说一下,并不是对达伦的回答进行贬低,那也是完全有效的。只是我个人的两分钱 :) - Leigh
4
使用 IN 关键字是更好的方式。 - Sagar Naliyapara

59
CASE WHEN ebv.db_no IN (22978, 23218, 23219) THEN 'WECS 9500' 
 ELSE 'WECS 9520' 
END as wecs_system 

56
您可以使用 WHEN 中的一个表达式,但不能混合使用两种表达式。
1. WHEN when_expression
当使用简单 CASE 格式时,WHEN 表达式是要将 input_expression 与之比较的一个简单表达式。when_expression 可以是任何有效的表达式。input_expression 和每个 when_expression 的数据类型必须相同或者必须进行隐式转换。
2. WHEN Boolean_expression
在使用搜索 CASE 格式时,Boolean_expression 是要评估的布尔表达式。Boolean_expression 可以是任何有效的布尔表达式。
您可以这样编程:
    CASE ProductLine
            WHEN 'R' THEN 'Road'
            WHEN 'M' THEN 'Mountain'
            WHEN 'T' THEN 'Touring'
            WHEN 'S' THEN 'Other sale items'
            ELSE 'Not for sale'

2.

    CASE
            WHEN ListPrice =  0 THEN 'Mfg item - not for resale'
            WHEN ListPrice < 50 THEN 'Under $50'
            WHEN ListPrice >= 50 and ListPrice < 250 THEN 'Under $250'
            WHEN ListPrice >= 250 and ListPrice < 1000 THEN 'Under $1000'
            ELSE 'Over $1000'
          END

但无论如何,您可以期望变量排名将在布尔表达式中进行比较。

请参见CASE (Transact-SQL)(MSDN)。


39

关于 CASE 的问题已经有很多答案了。我将解释何时以及如何使用 CASE

在 SQL 查询中,您可以随时使用 CASE 表达式。 CASE 表达式可以用于 SELECT 语句、WHERE 子句、ORDER BY 子句、HAVING 子句、INSERT、UPDATE 和 DELETE 语句。

CASE 表达式有以下两种格式:

  1. 简单 CASE 表达式

  2. CASE expression
    WHEN expression1 THEN Result1
    WHEN expression2 THEN Result2
    ELSE ResultN
    END
    

    这将一个表达式与一组简单的表达式进行比较,以找到结果。该表达式将表达式与每个WHEN子句中的表达式进行等效性比较。如果匹配WHEN子句内部的表达式,则会返回THEN子句中的表达式。

    这就是OP问题的所在。 22978 OR 23218 OR 23219 不会得到与表达式ebv.db_no相等的值。这就是为什么会出错的原因。输入表达式和每个when_expression的数据类型必须相同或必须进行隐式转换。

  3. 搜索CASE表达式

  4. CASE
    WHEN Boolean_expression1 THEN Result1
    WHEN Boolean_expression2 THEN Result2
    ELSE ResultN
    END
    

    此表达式评估一组布尔表达式以找出结果。此表达式允许比较运算符,并在每个布尔表达式中使用逻辑运算符AND/OR。

1.带有CASE表达式的SELECT语句

--Simple CASE expression: 
SELECT FirstName, State=(CASE StateCode
 WHEN 'MP' THEN 'Madhya Pradesh' 
 WHEN 'UP' THEN 'Uttar Pradesh' 
 WHEN 'DL' THEN 'Delhi' 
 ELSE NULL 
 END), PayRate
FROM dbo.Customer

-- Searched CASE expression:
SELECT FirstName,State=(CASE 
 WHEN StateCode = 'MP' THEN 'Madhya Pradesh' 
 WHEN StateCode = 'UP' THEN 'Uttar Pradesh' 
 WHEN StateCode = 'DL' THEN 'Delhi' 
 ELSE NULL 
 END), PayRate
FROM dbo.Customer

2. 使用CASE表达式的更新语句

-- Simple CASE expression: 
UPDATE Customer 
SET StateCode = CASE StateCode
 WHEN 'MP' THEN 'Madhya Pradesh' 
 WHEN 'UP' THEN 'Uttar Pradesh' 
 WHEN 'DL' THEN 'Delhi' 
 ELSE NULL 
 END 

-- Simple CASE expression: 
UPDATE Customer 
SET StateCode = CASE 
 WHEN StateCode = 'MP' THEN 'Madhya Pradesh' 
 WHEN StateCode = 'UP' THEN 'Uttar Pradesh' 
 WHEN StateCode = 'DL' THEN 'Delhi' 
 ELSE NULL 
 END 

3. 使用CASE表达式的ORDER BY子句

-- Simple CASE expression: 
SELECT * FROM dbo.Customer
ORDER BY 
 CASE Gender WHEN 'M' THEN FirstName END Desc,
 CASE Gender WHEN 'F' THEN LastName END ASC

-- Searched CASE expression: 
SELECT * FROM dbo.Customer
ORDER BY 
 CASE WHEN Gender='M' THEN FirstName END Desc,
 CASE WHEN Gender='F' THEN LastName END ASC

4. 使用CASE表达式的Having子句

-- Simple CASE expression: 
SELECT FirstName ,StateCode,Gender, Total=MAX(PayRate)
FROM dbo.Customer
GROUP BY StateCode,Gender,FirstName
HAVING (MAX(CASE Gender WHEN 'M' 
 THEN PayRate 
 ELSE NULL END) > 180.00
 OR MAX(CASE Gender WHEN 'F' 
 THEN PayRate 
 ELSE NULL END) > 170.00)

-- Searched CASE expression: 
SELECT FirstName ,StateCode,Gender, Total=MAX(PayRate)
FROM dbo.Customer
GROUP BY StateCode,Gender,FirstName
HAVING (MAX(CASE WHEN Gender = 'M' 
 THEN PayRate 
 ELSE NULL END) > 180.00
 OR MAX(CASE WHEN Gender = 'F' 
 THEN PayRate 
 ELSE NULL END) > 170.00)

希望这些用例能在将来帮助某人。

来源


34

尝试

CASE WHEN ebv.db_no IN (22978,23218,23219) THEN 'WECS 9500' ELSE 'WECS 9520' END

28
SELECT
  Store_Name,
  CASE Store_Name
    WHEN 'Los Angeles' THEN Sales * 2
    WHEN 'San Diego' THEN Sales * 1.5
    ELSE Sales
    END AS "New Sales",
  Txn_Date
FROM Store_Information;

1
点赞因为包含了一个ELSE Sales字段,如果在case语句中没有包含其他情况,则返回默认值,适用于商业查询。 - FoxDeploy

3
select id,phno,case gender
when 'G' then 'M'
when 'L' then 'F'
else
'No gender'
end
as gender 
from contacts

1
为什么你不解释这里正在做什么?给出完整的解释是很重要的,因为一些新手可能需要理解如何解决问题。 - Gerhard

3
UPDATE table_name 
  SET column_name=CASE 
WHEN column_name in ('value1', 'value2',.....) 
  THEN 'update_value' 
WHEN column_name in ('value1', 'value2',.....) 
  THEN 'update_value' 
END

table_name = 您要执行操作的表的名称。

column_name = 您要设置值的列/字段的名称。

update_value = 您要设置的column_name的值。


11
虽然这段代码可能解决了提问者的问题,但对于未来的读者来说,一些解释性的话语会更有帮助。 - Thom

1
CASE
  WHEN ebv.db_no = 22978 OR 
       ebv.db_no = 23218 OR
       ebv.db_no = 23219
  THEN 'WECS 9500' 
  ELSE 'WECS 9520' 
END as wecs_system 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接