Éviter plusieurs expressions `ou`


13

J'ai l'oracle SQL suivant et ses travaux et tout, mais c'est assez moche avec tous les ors. Existe-t-il une manière plus concise de procéder?

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

Réponses:


21

Vous pourriez préférer quelque chose comme ça:

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

DBFiddle ici


2
Je souhaite que MS SQL Server ait cette syntaxe.
Ross Presser

@RossPresser Je pense qu'il y a un élément / suggestion Connect pour la syntaxe à ajouter. Vous pouvez voter;)
ypercubeᵀᴹ

Je trouve qu'il y a quelque chose à peu près aussi capable: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

mais je voudrais cette syntaxe réelle. Vous savez où se trouve l'élément Connect?
Ross Presser

@RossPresser le voici: ajouter la prise en charge des constructeurs de valeurs de lignes standard ANSI La réponse de MS était: "Bonjour. Merci pour vos commentaires. Nous envisageons certainement les constructeurs de valeurs de lignes pour une future version de SQL Server." Au moins la demande est toujours ouverte, 10 ans maintenant.
ypercubeᵀᴹ

11

En termes de nettoyage de code pur, ce qui suit semble plus propre:

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

Selon l'application et la fréquence de réutilisation de la logique, il peut également être utile de configurer une table de recherche pour appliquer la logique:

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

Voici une autre façon de procéder. L'utilisation de où (col1, col2) peut empêcher Oracle d'utiliser des index, mais cela ressemble à une table pour la requête, donc cela pourrait mieux fonctionner. Vous saurez une fois que vous aurez testé les différentes versions.

  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 ici

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.