複数の `or`式を避ける


13

私は次のOracle SQLとその作品を持っていますが、すべてのもので非常にquiteいですor。これを行うより簡潔な方法はありますか?

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にこの構文があればいいのにと思います。
ロスプレッサー

@RossPresser構文を追加するための接続アイテム/提案があると思います。投票できます;)
ypercubeᵀᴹ17年

私はそこことがわかっているおおよそできるような何か: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
ロス押え

しかし、私はこの実際の構文が欲しいです。Connectアイテムはどこにあるのでしょうか?
ロスプレッサー

@RossPresserは次のとおりです。ANSI 標準行値コンストラクターサポートを追加します。MSからの回答は、「こんにちは。ご意見をお寄せいただきありがとうございます。SQLServerの今後のリリースで行値コンストラクターを検討しています。」少なくとも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.