É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.