Evitare espressioni multiple `o`


13

Ho il seguente oracolo SQL e le sue opere e tutto, ma è abbastanza brutto con tutte le ors. C'è un modo più conciso per farlo?

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

Risposte:


21

Potresti preferire qualcosa del genere:

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

DBFiddle qui


2
Vorrei che MS SQL Server avesse questa sintassi.
Ross Presser,

@RossPresser Penso che ci sia un elemento / suggerimento Connect da aggiungere alla sintassi. Puoi votare;)
ypercubeᵀᴹ

Ho trovato che ci sia qualcosa di più o meno capace: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

ma vorrei questa sintassi reale. Qualche idea su dove sia l'elemento Connect?
Ross Presser,

@RossPresser eccolo qui: aggiungi il supporto per i costruttori di valori di riga standard ANSI La risposta di MS è stata: "Ciao. Grazie per il tuo feedback. Stiamo sicuramente prendendo in considerazione i costruttori di valori di riga per una versione futura di SQL Server." Almeno la richiesta è ancora aperta, ormai 10 anni.
ypercubeᵀᴹ

11

In termini di pura pulizia del codice, il seguente aspetto appare più pulito:

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

A seconda dell'applicazione e della frequenza con cui la logica verrà riutilizzata, potrebbe anche valere la pena impostare una tabella di ricerca per applicare la logica:

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

Ecco un altro modo per farlo. L'uso di where (col1, col2) potrebbe far sì che Oracle non utilizzi alcun indice, ma questo sembra una tabella per la query, quindi potrebbe funzionare meglio. Saprai una volta testate le varie versioni.

  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 Here

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.