2010-12-15 96 views
2

Disons que je donne les résultats suivants:Comment Oracle gère-t-il une condition de clause where comparée à une sous-requête avec un résultat constant?

select primary_id 
from myschema.table_a 
where row_changed_date > (select last_refreshed 
          from myschema.last_refresh lr 
          where asset_type = 0); 

Le résultat de la sous-requête ne changera pas entre les actifs. Je veux techniquement comparer directement avec une valeur constante, mais je ne veux pas exécuter une requête séparée pour obtenir cette constante. Oracle exécutera-t-il la sous-requête pour chaque passage à travers l'itération? Y a-t-il une meilleure manière de faire cela?

Répondre

3

Vous devez vous assurer que votre sous-requête renvoie une seule ligne, ou utiliser une comparaison qualifiée:

WHERE row_changed_date > ALL (SELECT last_refreshed ...) 

Ou:

WHERE row_changed_date > (SELECT MAX(last_refreshed) ...) 

En supposant asset_type est une colonne dans la table last_refresh, puis Oracle calculera la sous-requête une fois. S'il s'agit réellement d'une colonne dans la table table_a, vous avez une sous-requête corrélée; cela doit être évalué par rangée.

Cette réponse est réellement DBMS-agnostic - les règles s'appliquent à Oracle ainsi qu'à d'autres SGBD SQL.

+0

Oui, il est préférable d'ajouter ces alias de table aux colonnes de la sous-requête. –

1

Dans votre exemple utilisant une sous-requête - non, Oracle n'exécuterait pas la sous-requête pour chaque ligne. Une sous-requête corrélée le serait.

Utilisation:

SELECT a.primary_id 
    FROM MYSCHEMA.TABLE_A a 
    JOIN MYSCHEMA.LAST_REFRESH lr ON lr.last_refreshed < a.row_changed_date 
           AND lr.asset_type = 0 

autre version en OÙ:

SELECT a.primary_id 
    FROM MYSCHEMA.TABLE_A a 
    JOIN MYSCHEMA.LAST_REFRESH lr ON lr.last_refreshed < a.row_changed_date 
WHERE lr.asset_type = 0 

En raison de l'utilisation d'un INNER JOIN, il n'y a pas de différence dans les résultats ou la performance entre l'une de ces versions de la requête. Ce ne serait pas le cas si vous utilisiez OUTER JOINS (LEFT, RIGHT).