หรือไม่รองรับคำสั่ง CASE ใน SQL Server


572

ORผู้ประกอบการในWHENประโยคของCASEคำสั่งที่ไม่สนับสนุน ฉันจะทำสิ่งนี้ได้อย่างไร

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

SQL Standard อนุญาตให้มีหลายค่า: stackoverflow.com/a/54562580/5070879
Lukasz Szozda

คำตอบ:


1079

รูปแบบนั้นต้องการให้คุณใช้:

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' ถึงทำงานและไม่ใช่ '='
ฮัน

25
=จะทำงานถ้าคุณเปรียบเทียบกับค่าเดียว อย่างไรก็ตาม(22978, 23218, 23219)เป็นอาร์เรย์และINจำเป็นต้องจับคู่ค่าใดค่าหนึ่งเท่านั้น
LdTrigger

2
สิ่งนี้มีปัญหาจริง ๆ ไม่สามารถจัดการกับ "หรือ" ในคำสั่งกรณี มาเวลา Microsoft เพื่อเติบโตขึ้นจากสถานะฐานข้อมูลของเล่น
รวย Bianco

1
"ไม่สามารถจัดการกับ" หรือ "ในคำสั่งกรณี" .. hmmm .... ฉันไม่คิดว่า ive เคยเห็นสวิตช์ยอมรับ "หรือ" ในภาษาใด ๆ ดูเหมือนจะเอาชนะวัตถุประสงค์ของสวิตช์ ภาษาใดบ้างที่ยอมรับ "หรือ" ในกรณี
Heriberto Lugo

2
@Heriberto Lugo ฉันไม่รู้ว่าคุณรู้จักภาษากี่ภาษา แต่อย่างน้อยก็มีน้อย VB.NET และ C # สามารถใช้พวกมันได้ด้วยการแยกคอมม่า มันไม่ได้พ่ายแพ้อะไรเลยเพราะมันจะช่วยคุณไม่ให้ทำซ้ำรหัสเดิมซ้ำหลายกรณี
Johnny Prescott

249
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 

38
upvoted - การตอบกลับนี้เป็นการเพิ่มมูลค่า มันเหมาะกับคำถามของ OP อย่างใกล้ชิดยิ่งขึ้นและถ้าคุณต้องการซ้อน CASE-WHENS บางไวยากรณ์นี้จะช่วยลดรหัสที่จำเป็นอย่างมาก
Matt Kemp

1
@Leigh ฉันขอขอบคุณคำตอบนี้ มันเป็นเรื่องดีที่มีรูปแบบที่แตกต่างกันทั้งหมดในหนึ่งเธรดและทำให้สามารถใช้เป็นข้อมูลอ้างอิงได้มากขึ้น
Jason Wheeler

3
@Bigwheels - ว้าว .. นี่เป็นเวลานานแล้ว ฉันอาจไม่เห็นด้วยเพราะเหตุผลมันเป็นเหมือนกับตอบของคนอื่น ที่กล่าวว่าคุณและแมตต์ให้คะแนนที่ถูกต้อง หากคำถามคือ "สิ่งที่เป็นไวยากรณ์ที่ถูกต้องใช้หรือเพียง " นี้ให้คำตอบ อย่างไรก็ตามหาก "การลดไวยากรณ์ที่จำเป็น" เป็นเป้าหมายการตอบสนองที่ยอมรับจะมีขนาดเล็กลง BTW มันไม่ใช่คำสแลมของคำตอบของดาร์เรนซึ่งใช้ได้อย่างสมบูรณ์แบบ แค่ $ 0.02 ของฉัน :)
Leigh

2
การใช้ INคำหลักเป็นวิธีที่ดีกว่ามาก
Sagar Naliyapara


53

คุณสามารถใช้หนึ่งในการแสดงออกที่เมื่อมี แต่คุณไม่สามารถผสมทั้งสอง

  1. เมื่อใดเมื่อแสดงออกมา

    เป็นนิพจน์อย่างง่าย ๆ ที่ input_expression ถูกเปรียบเทียบเมื่อใช้รูปแบบ CASE แบบง่าย when_expression คือการแสดงออกที่ถูกต้องใด ๆ ชนิดข้อมูลของ input_expression และแต่ละ when_expression จะต้องเหมือนกันหรือจะต้องมีการแปลงโดยนัย

  2. เมื่อ Boolean_expression

    นิพจน์บูลีนถูกประเมินค่าเมื่อใช้รูปแบบ CASE ที่ค้นหาหรือไม่ Boolean_expression เป็นนิพจน์บูลีนที่ถูกต้อง

คุณสามารถตั้งโปรแกรม:

1

    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)


37

มีคำตอบมากมายเกี่ยวกับเรื่องCASEนี้แล้ว ฉันจะอธิบายเวลาและวิธีการใช้CASEผมจะอธิบายเมื่อและวิธีการใช้

คุณสามารถใช้นิพจน์ CASE ได้ทุกที่ในแบบสอบถาม SQL สามารถใช้นิพจน์ CASE ภายในคำสั่ง SELECT, WHERE clauses, เรียงลำดับตามคำสั่ง, HAVING clauses, แทรก, UPDATE และคำสั่ง DELETE

นิพจน์ CASE มีสองรูปแบบต่อไปนี้:

  1. การแสดงออกกรณีง่าย

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

    สิ่งนี้เปรียบเทียบนิพจน์กับชุดของนิพจน์อย่างง่ายเพื่อค้นหาผลลัพธ์ นิพจน์นี้เปรียบเทียบนิพจน์กับนิพจน์ในแต่ละส่วนของ WHEN เพื่อความเท่าเทียม หากการแสดงออกภายในข้อ WHEN ถูกจับคู่การแสดงออกในประโยคนั้นจะถูกส่งกลับ

    นี่คือที่คำถามของ OP ลดลง 22978 OR 23218 OR 23219จะไม่ได้รับค่าเท่ากับนิพจน์เช่น ebv.db_no นั่นเป็นสาเหตุที่ทำให้เกิดข้อผิดพลาด ชนิดข้อมูลของ input_expression และแต่ละ when_expression จะต้องเหมือนกันหรือจะต้องมีการแปลงโดยนัย

  2. ค้นหากรณีของนิพจน์

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

    นิพจน์นี้ประเมินชุดของนิพจน์บูลีนเพื่อค้นหาผลลัพธ์ นิพจน์นี้อนุญาตให้ตัวดำเนินการเปรียบเทียบและตัวดำเนินการเชิงตรรกะและ / หรือมีในแต่ละนิพจน์บูลีน

1.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.ORDER โดยส่วนคำสั่งที่มีการแสดงออกกรณี

-- 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

-- 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)

หวังว่ากรณีการใช้งานนี้จะช่วยให้ใครบางคนในอนาคต

แหล่ง



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 Barnard

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
ในขณะที่รหัสนี้อาจช่วยแก้ปัญหาของ OP คำอธิบายเล็กน้อยจะมีประโยชน์มากยิ่งขึ้นสำหรับผู้อ่านในอนาคต
Thom

-5
Select s.stock_code,s.stock_desc,s.stock_desc_ar,
mc.category_name,s.sel_price,
case when s.allow_discount=0 then 'Non Promotional Item' else 'Prmotional 
item' end 'Promotion'
From tbl_stock s inner join tbl_stock_category c on s.stock_id=c.stock_id
inner join tbl_category mc on c.category_id=mc.category_id
where mc.category_id=2 and s.isSerialBased=0 

1
คำตอบนี้ดูเหมือนจะไม่เกี่ยวข้องกับคำถาม
LarsTech

4
โปรดอย่าโพสต์รหัสเปลือยและให้คำอธิบายว่าโค้ดของคุณกำลังทำอะไรอยู่
Jonathan Mee
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.