여러 개의 '또는'표현 피하기


13

나는 다음과 같은 오라클 SQL과 그 작품과 모든 것을 가지고 있지만 모든 것들과 함께 아주 추악합니다 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에이 구문이 있었으면합니다.
Ross Presser

@RossPresser 구문이 추가 될 Connect 항목 / 제안이 있다고 생각합니다. ;)
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
Ross 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.