หลีกเลี่ยงการแสดงออกหลายหรือ `


13

ฉันมี SQL oracle ต่อไปและผลงานของตนและ แต่มันค่อนข้างน่าเกลียดที่มีทั้งหมดของors มีวิธีรัดกุมกว่านี้ไหม?

SELECT * FROM foobar WHERE
  (SUBJECT ='STAT' and TERM ='111') or  
  (SUBJECT ='STAT' and TERM ='222') or  
  (SUBJECT ='ENGLISH' and TERM ='555') or 
  (SUBJECT ='COMM' and TERM ='444') or
  (SUBJECT ='COMM' and TERM ='333') or  
  (SUBJECT ='STAT' and TERM ='666')
  ...

คำตอบ:


21

คุณอาจชอบสิ่งนี้:

select *
from foobar
where (subject,term) in ( ('STAT','111')
                         ,('STAT','222')
                         ,('ENGLISH','555')
                         ,('COMM','444')
                         ,('COMM','333')
                         ,('STAT','222')
                         ,('STAT','666') 
                        );

DBFiddle ที่นี่


2
ฉันหวังว่า MS SQL Server มีไวยากรณ์นี้
Ross Presser

@RossPresser ฉันคิดว่ามีรายการเชื่อมต่อ / คำแนะนำสำหรับไวยากรณ์ที่จะเพิ่ม คุณสามารถลงคะแนน;)
ypercubeᵀᴹ

ผมพบว่ามีเป็นบางสิ่งบางอย่างคร่าว ๆ ความสามารถ:SELECT * FROM foobar INNER JOIN (SELECT * FROM (VALUES ('4','a'),('5','b')) AS myTable(subject,term)) ON myTable.subject=foobar.table and mytable.term=foobar.term
รอสส์ Presser

แต่ฉันต้องการไวยากรณ์ที่แท้จริงนี้ แนวคิดใดที่รายการเชื่อมต่ออยู่
Ross Presser

@RossPresser ที่นี่คือ: เพิ่มการสนับสนุนสำหรับตัวสร้างค่าแถวมาตรฐาน ANSIคำตอบจาก MS คือ: "สวัสดีขอบคุณสำหรับความคิดเห็นของคุณเรากำลังพิจารณาตัวสร้างค่าแถวสำหรับ SQL Server ในอนาคตอย่างแน่นอน" อย่างน้อยคำขอก็ยังคงเปิดอยู่ 10 ปีแล้ว
ypercubeᵀᴹ

11

ในแง่ของการทำความสะอาดรหัสบริสุทธิ์

SELECT * 
  FROM foobar 
  WHERE (SUBJECT = 'STAT' and TERM IN ('111','222','666') )
    OR  (SUBJECT = 'COMM' and TERM IN ('333','444') )
    OR  (SUBJECT = 'ENGLISH' and TERM = '555' ) ;

ขึ้นอยู่กับแอปพลิเคชันและความถี่ที่จะใช้ซ้ำตรรกะมันอาจคุ้มค่าที่จะตั้งค่าตารางการค้นหาเพื่อใช้ตรรกะ:

CREATE TABLE foobar_lookup (SUBJECT VARCHAR2(7), TERM VARCHAR2(3)) ;

INSERT INTO foobar_lookup SELECT 'STAT',    '111' FROM dual ;
INSERT INTO foobar_lookup SELECT 'STAT',    '222' FROM dual ;
INSERT INTO foobar_lookup SELECT 'STAT',    '666' FROM dual ;
INSERT INTO foobar_lookup SELECT 'COMM',    '444' FROM dual ;
INSERT INTO foobar_lookup SELECT 'COMM',    '333' FROM dual ;
INSERT INTO foobar_lookup SELECT 'ENGLISH', '555' FROM dual ;

SELECT f.* FROM foobar f
JOIN foobar_lookup fl 
    ON fl.subject = f.subject
    AND fl.term = f.term ;

4

นี่เป็นอีกวิธีที่จะทำ การใช้ where (col1, col2) อาจทำให้ Oracle ไม่ใช้ดัชนีใด ๆ แต่สิ่งนี้ดูเหมือนว่าตารางในแบบสอบถามดังนั้นจึงอาจทำงานได้ดีขึ้น คุณจะรู้เมื่อคุณทดสอบเวอร์ชันต่างๆ

  WITH subject_terms 
            (subject,   term) AS
    ( SELECT 'STAT'   , '111' FROM dual UNION ALL
      SELECT 'STAT'   , '222' FROM dual UNION ALL
      SELECT 'ENGLISH', '555' FROM dual UNION ALL
      SELECT 'COMM'   , '444' FROM dual UNION ALL
      SELECT 'COMM'   , '333' FROM dual UNION ALL
      SELECT 'STAT'   , '666' FROM dual )
SELECT * 
  FROM foobar             fb
 INNER JOIN subject_terms st
    ON fb.subject = st.subject
   AND fb.term    = st.term;

DBFiddle ที่นี่

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