Birden fazla "veya" ifadesinden kaçınma


13

Aşağıdaki oracle SQL ve çalışmaları ve hepsi var ama tüm ors ile oldukça çirkin . Bunu yapmanın daha kısa bir yolu var mı?

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

Yanıtlar:


21

Bunun gibi bir şeyi tercih edebilirsiniz:

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

DBFiddle burada


2
Keşke MS SQL Server bu sözdizimine sahip olsaydı.
Ross Presser

@RossPresser Eklenecek sözdizimi için bir Connect öğesi / önerisi olduğunu düşünüyorum. Oy verebilirsiniz;)
ypercubeᵀᴹ

Orada bulundu olduğu kabaca yetenekli olarak bir şey: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 Baskı

ama bu gerçek sözdizimini istiyorum. Connect öğesinin nerede olduğu hakkında bir fikrin var mı?
Ross Presser

@RossPresser burada: ANSI standart satır değeri yapıcıları için destek ekleyin MS'in yanıtı şuydu: "Merhaba. Geri bildiriminiz için teşekkür ederiz. SQL Server'ın gelecekteki bir sürümü için kesinlikle satır değeri yapıcılarını düşünüyoruz." En azından istek 10 yıl şimdi hala açık.
ypercubeᵀᴹ

11

Saf kod temizliği açısından, aşağıdakiler daha temiz görünür:

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

Uygulamaya ve mantığın ne sıklıkta yeniden kullanılacağına bağlı olarak, mantığı uygulamak için bir arama tablosu oluşturmaya değer olabilir:

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

İşte bunu yapmanın başka bir yolu. Where (col1, col2) kullanmak Oracle'ın herhangi bir dizin kullanmamasına neden olabilir, ancak bu sorgu için bir tablo gibi görünür, bu yüzden daha iyi çalışabilir. Çeşitli sürümleri test ettikten sonra bileceksiniz.

  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 Burada

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.