SQL - Relacja między podkwerendą a tabelą zewnętrzną

Problem

Muszę lepiej zrozumieć zasady dotyczące tego, kiedy mogę odwołać się do zewnętrznej tabeli w podzapytaniu i kiedy (i dlaczego) jest to niewłaściwa prośba. Odkryłem duplikację w zapytaniu SQL Oracle, które próbuję refaktoryzować, ale napotykam problemy, gdy próbuję przekształcić tabelę, do której się odwołuję, w zgrupowaną podkwerendę.

Poniższe stwierdzenie działa odpowiednio:

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

Niestety tabela 2 czasami ma zduplikowane rekordy, więc najpierw muszę agregować t2, zanim dołączę go do t1. Jednak gdy próbuję zawinąć go w podzapytanie w celu wykonania tej operacji, nagle silnik SQL nie może już rozpoznać zewnętrznej tabeli.

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

Wiem, że są to zasadniczo różne zapytania, które pytam kompilatorowi, aby zestawił, ale nie widzę powodu, dla którego ten działałby, ale nie drugi.

Wiem, że mogę zduplikować odwołania do tabeli w moim podzapytaniu i skutecznie oddzielić moje podzapytanie od zewnętrznej tabeli, ale wydaje się to naprawdę brzydkim sposobem wykonania tego zadania (co z całą duplikacją kodu i przetwarzania).

Pomocne referencje

Znalazłem ten fantastyczny opis kolejności wykonywania klauzul w SQL Server: (Klauzula INNER JOIN ON vs WHERE). Używam Oracle, ale sądzę, że byłoby to standardowe rozwiązanie. Istnieje wyraźny porządek oceny klauzul (z FROM jako pierwszym), więc sądzę, że każda klauzula występująca w dalszej części listy będzie miała dostęp do wszystkich informacji wcześniej przetworzonych. Mogę tylko założyć, że moje drugie zapytanie w jakiś sposób zmienia porządek, tak że moje podzapytanie jest oceniane zbyt wcześnie?

Ponadto zadałem podobne pytanie (Odwoływanie się do tabel zapytań zewnętrznych w podzapytaniu ) ale chociaż wkład był dobry, nigdy tak naprawdę nie wyjaśnili, dlaczego nie mógł zrobić tego, co robi, i po prostu podał alternatywne rozwiązanie swojego problemu. Próbowałem ich alternatywnych rozwiązań, ale powoduje to inne problemy. Mianowicie, to podzapytanie z odniesieniem do daty ma fundamentalne znaczenie dla całej operacji, więc nie mogę się go pozbyć.

pytania

Chcę zrozumieć, co tutaj zrobiłem ... Dlaczego moje wstępne podzapytanie może zobaczyć zewnętrzną tabelę, ale nie po opakowaniu całej instrukcji w podzapytanie?

To powiedziawszy, jeśli tego, co próbuję zrobić, nie da się zrobić, jaki jest najlepszy sposób refaktoryzacji pierwszego zapytania, aby wyeliminować duplikację? Czy powinienem odwołać się do tabeli 1 dwa razy (z całą potrzebną duplikacją)? Czy istnieje (prawdopodobnie) lepszy sposób na rozwiązanie tego problemu?

Z góry dziękuję!

------EDYTOWAĆ------

Jak niektórzy przypuszczali, powyższe zapytania nie są właściwie zapytaniem, które refaktoryzuję, ale przykładem problemu, w którym się znalazłem. Zapytanie, nad którym pracuję, jest o wiele bardziej skomplikowane, więc waham się, czy zamieścić je tutaj, ponieważ obawiam się, że ludzie odsuną się od niego.

------AKTUALIZACJA------

Więc uruchomiłem to przez innego programistę i miał jedno możliwe wyjaśnienie, dlaczego moje podzapytanie traci dostęp do t1. Ponieważ zawijam to podzapytanie w nawias, on myśli, że to podzapytanie jest oceniane przed oceną mojej tabeli t1. Z pewnością wyjaśniłoby to błąd „ORA-00904:„ t1 ”.„ Id ”: błędny identyfikator”. Sugerowałoby to również, że podobnie jak arytmetyczna kolejność operacji, dodawanie parenów do instrukcji daje jej priorytet w ramach niektórych ocen klauzul. Nadal chciałbym, żeby ekspert rozważył, czy zgadzają się / nie zgadzają, co jest logicznym wyjaśnieniem tego, co widzę tutaj.

questionAnswers(3)

yourAnswerToTheQuestion