web-dev-qa-db-fra.com

Vérifiez si l'une des valeurs se trouve dans un résultat de sous-requête

J'ai une sous-requête compliquée qui renvoie une liste d'ID de commande. J'ai besoin d'obtenir une liste de clients qui ont ces commandes. Le problème est qu'il existe deux façons d'affecter un client à une commande (l'un des deux champs). Je pourrais juste faire des trucs comme ça:

 select *
 from Customers
 where orderId in (select...) 
 or secondaryOrderId in (select ...)

Le problème est que la sous-requête est énorme, à la fois en temps d'exécution et en espace d'écran. Existe-t-il un moyen de vérifier si n des champs contient l'un des résultats souhaités?

8
user63844

Essayer:

where exists (select * .... 
        where Customers.orderId = ... 
        or Customers.secondaryId = ...
     )

Par exemple, si vous envisagiez:

where orderId in (select value from ...)
or secondaryorderid in (select value from ...)

Ensuite, vous faites en sorte que vous n'appeliez votre sous-requête qu'une seule fois, et que vous y intégriez votre clause OR).

 where exists (select * from ... 
        where Customers.orderId = value 
        or Customers.secondaryOrderId = value
     )

Le but de tout cela est de s'assurer que la sous-requête compliquée n'est exécutée qu'une seule fois. Cela ne se produit pas avec un CTE ou en remplaçant deux IN par deux EXISTS.

10
Rob Farley

Votre requête devrait probablement être réécrite sous la forme d'un exists au lieu d'un in

Voir ce lien pour plus d'exemples.

Votre requête ressemblerait alors à quelque chose comme

select *
from Customers C
where exists (select 'x' from ordertable o where c.orderid = o.orderid) 
or exists (select 'x' from ordertable o where c.secondaryOrderId = o.orderid) 

Si les deux sous-requêtes sont identiques, vous pouvez supprimer l'une d'entre elles et les combiner comme ceci

select *
from Customers C
where exists (select 'x' from ordertable o where c.orderid = o.orderid or c.secondaryOrderId = o.orderid) 

Pourquoi ne pas utiliser une clause Common Table Expression aka with? Il est conçu à cet effet (entre autres).

with orderIds as (
  select orderId
  from ...
)
select *
from Customers
where orderId in (select orderId from orderIds) 
or secondaryOrderId in (select orderId from orderIds);

Voir https://msdn.Microsoft.com/en-us/library/ms175972%28v=sql.105%29.aspx pour la documentation de Microsoft.

2
Colin 't Hart