SQL - Relation entre une sous-Requête et une Table Externe

Problème

J'ai besoin de mieux comprendre les règles au sujet de quand je peut faire référence à une table externe dans une sous-requête et quand (et pourquoi) qui est inadapté à la demande. J'ai découvert une duplication dans un Oracle SQL de la requête, je suis en train de revoir, mais je suis en cours d'exécution dans des problèmes lorsque j'essaie de changer ma table référencée dans un regroupées sous-requête.

La déclaration suivante fonctionne correctement:

SELECT  t1.*  
FROM    table1 t1, 
INNER JOIN table2 t2 
        on t1.id = t2.id        
        and t2.date = (SELECT max(date) 
                       FROM   table2  
                       WHERE  id = t1.id) --This subquery has access to t1

Malheureusement table2 a parfois des enregistrements en double, donc j'ai besoin d'agréger t2 d'abord avant de me joindre à t1. Cependant lorsque je l'ai essayer et l'envelopper dans une sous-requête pour accomplir cette opération, tout à coup le moteur SQL ne peut pas reconnaître la table externe.

SELECT  t1.* 
FROM    table1 t1, 
INNER JOIN (SELECT * 
            FROM  table2 t2
            WHERE t1.id = t2.id              --This loses access to t1
              and t2.date = (SELECT max(date) 
                             FROM   table2 
                             WHERE  id = t1.id)) sub on t1.id = sub.id 
                             --Subquery loses access to t1

Je sais que ce sont fondamentalement différentes questions que je me demande au compilateur de mettre ensemble, mais je ne vois pas pourquoi l'un serait de travailler mais pas les autres.

Je sais que je peux dupliquer le tableau des références dans mon sous-requête et efficacement détacher mon sous-requête de la table externe, mais qui semble vraiment comme un laid façon d'accomplir cette tâche (ce avec toute la duplication de code et de traitement).

Références Utiles

  • J'ai trouvé cela fantastique description de l'ordre dans lequel les clauses sont exécutées dans SQL Server: (JOINTURE INTERNE SUR vs clause where). Je suis à l'aide d'Oracle, mais je pense que cela devrait être la norme à travers le conseil d'administration. Il est clair que l'ordre de la clause d'évaluation (à PARTIR de la première) donc je pense qu'une clause quelconque des présentes plus bas dans la liste aurait accès à toutes les informations traitées précédemment. Je ne peux que supposer mon 2ème requête en quelque sorte modifications de la commande ainsi que mon sous-requête est en cours d'évaluation trop tôt?
  • En plus, j'ai une question similaire posée (Référencement requête externe de tables dans une sous-requête
    ) mais, alors que l'entrée était bonne, ils n'ont jamais vraiment expliqué pourquoi il ne pouvait pas faire ce qu'il fait et juste donné d'autres solutions à son problème. J'ai essayé de leurs solutions de remplacement, mais il me causer d'autres problèmes. À savoir, que la sous-requête avec la date de référence est fondamentale pour l'ensemble de l'opération donc je ne peux pas m'en débarrasser.

Questions

  • Je veux comprendre ce que j'ai fait ici... Pourquoi ma première sous-requête, voir la table externe, mais pas après que j'ai renvoyer l'ensemble de la déclaration dans une sous-requête?
  • Cela dit, si ce que je suis en train de faire ne peut pas être fait, quelle est la meilleure façon de refactoring la première requête pour éliminer la duplication? Dois-je référence table1 deux fois (avec toutes les répétitions que l'exige)? Ou est-il (probablement) une meilleure façon de s'attaquer à ce problème?

Merci d'avance!

------ MODIFIER------

Comme certains l'ont deviné, ces requêtes ci-dessus ne sont pas le fait de requête je suis refactoring mais, par exemple, le problème, je suis en cours d'exécution dans. La requête je travaille est beaucoup plus compliqué, donc j'hésite à le poster ici car j'ai peur qu'il va amener les gens hors-piste.

------ Mise à JOUR------

Alors, j'ai couru ce par un autre développeur et qu'il avait une explication possible de mon sous-requête est en train de perdre l'accès à t1. Parce que je suis habillage de la sous-requête entre parenthèses, il pense que la sous-requête est en cours d'évaluation avant que mon la table t1 qui est évalué. Ce serait certainement expliquer le " ORA-00904: "t1"."id": identifiant invalide' erreur que j'ai reçu. Il suggère également que, comme l'arithmétique d'ordre des opérations, que l'ajout de parenthèses à une déclaration qu'elle lui donne la priorité à l'intérieur de certains clause évaluations. J'ai toujours l'amour pour un expert de se prononcer s'ils sont d'accord ou en désaccord c'est une explication logique de ce que je vois ici.

Une table dérivée ne peut pas être corrélés. Il doit se tenir debout seul. Si vous pouvez vous joindre à elle. vous pouvez utiliser APPLY où vous avez besoin d'une sorte de corrélation table dérivée.
Martin.... sincèrement, je vous remercie! En fonction de votre commentaire que j'ai été capable de faire un peu de recherches et découvert que ma requête n'est pas réellement tirer des données comment j'ai pensé à l'origine. Aussi de vos conseils d'utilisation s'Appliquent semble très applicable (bien que pour moi, la syntaxe est un peu différente que je suis à l'aide d'Oracle). Apprécie beaucoup les conseils - en fait, si vous le présenter comme une réponse, je vais le marquer comme étant la bonne.

OriginalL'auteur DanK | 2013-11-20