Tránh nhiều biểu thức `hoặc`


13

Tôi có SQL tiên tri sau đây và tất cả các công việc của nó, nhưng nó khá xấu với tất cả các ors. Có cách nào ngắn gọn hơn để làm điều này?

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

Câu trả lời:


21

Bạn có thể thích một cái gì đó như thế này:

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

DBFiddle tại đây


2
Tôi muốn MS SQL Server có cú pháp này.
Ross Presser

@RossPresser Tôi nghĩ rằng có một mục Kết nối / đề xuất cho cú pháp được thêm vào. Bạn có thể bình chọn;)
ypercubeᵀᴹ 17/2/2017

Tôi thấy rằng có một cái gì đó gần như có khả năng: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
Ross tay ép

nhưng tôi muốn cú pháp thực tế này. Bất kỳ ý tưởng nơi mục Connect là?
Ross Presser

@RossPresser đây là: Thêm hỗ trợ cho các nhà xây dựng giá trị hàng tiêu chuẩn ANSI Câu trả lời từ MS là: "Xin chào. Cảm ơn bạn đã phản hồi. Chúng tôi chắc chắn đang xem xét các nhà xây dựng giá trị hàng để phát hành SQL Server trong tương lai." Ít nhất là yêu cầu vẫn mở, 10 năm nay.
ypercubeᵀᴹ

11

Về mặt làm sạch mã thuần túy, sau đây có vẻ sạch hơn:

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

Tùy thuộc vào ứng dụng và tần suất sử dụng logic, nó cũng có thể đáng để thiết lập bảng tra cứu để áp dụng logic:

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

Đây là một cách khác để làm điều đó. Sử dụng where (col1, col2) có thể khiến Oracle không sử dụng bất kỳ chỉ mục nào, nhưng điều này trông giống như một bảng cho truy vấn, vì vậy nó có thể hoạt động tốt hơn. Bạn sẽ biết một khi bạn kiểm tra các phiên bản khác nhau.

  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 đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.