2010-06-16 14 views
13

Czy istnieje sposób, aby dać podkwerenda w Oracle 11g alias jak:Czy istnieje sposób na podzapytanie alias w Oracle 11g SQL?

select * 
from 
    (select client_ref_id, request from some_table where message_type = 1) abc, 
    (select client_ref_id, response from some_table where message_type = 2) defg 
where 
    abc.client_ref_id = def.client_ref_id; 

W przeciwnym razie istnieje sposób, aby złączyć dwa podzapytania w oparciu o client_ref_id. Zdaję sobie sprawę, że istnieje samo sprzężenie, ale w bazie danych, którą uruchamiam na łączeniu się, może zająć do 5 minut (w dzienniku kwerendy znajduje się dodatkowa logika, ale ustaliłem, że samo łączenie jest tym, co jest powodując problem). Poszczególne podzapytania zajmują tylko kilka sekund. Samo dołączyć zapytanie wyglądał:

select st.request, st1.request 
from 
    some_table st, some_table st1 
where 
    st.client_ref_id = st1.client_ref_id; 
+0

Po prostu ciekawa, jak dobrze przyjęła się zaakceptowana odpowiedź? – DCookie

+1

Nie zorientowałeś się, że to samo-łączenie. Wykonaj identyczną kopię tabeli, indeksów i statystyk i sprawdź, czy otrzymałeś taki sam czas. Lepsze pytanie brzmiałoby: "Pomóż mi dostroić to zapytanie" i opublikuj zapytanie FULL oraz plan wyjaśniający. –

Odpowiedz

16
 
WITH abc as (select client_ref_id, request from some_table where message_type = 1) 
select * 
from abc 
    inner join 
    (select client_ref_id, response from some_table where message_type = 2) defg 
on abc.client_ref_id = def.client_ref_id; 
+0

Jaki jest termin techniczny dla części "WITH abc as (select ...)"? Jeśli ktoś chciałby zbadać jego możliwości. – SeaBass

+2

@SeaBass: Common Table Expressions, często skracane do CTE (często używane również jako nazwa/alias, chociaż tym razem nie będę tego robić). Zauważ, że obie "tabele" mogły być wykonane jako część CTE, chciałem tylko pokazać obie opcje, tak samo zrobiłem jeden i drugi, drugi. – jmoreno

5

nie mam instancję Oracle przetestować z, ale to, co pisał powinien być ważny ANSI-89 JOIN składni. Oto w ANSI-92:

SELECT * 
    FROM (SELECT client_ref_id, request 
      FROM SOME_TABLE 
     WHERE message_type = 1) abc 
    JOIN (SELECT client_ref_id, request 
      FROM SOME_TABLE 
     WHERE message_type = 1) defg ON defg.client_ref_id = abc.client_ref_id 
3

Twoje zapytanie powinno być w porządku.

Alternatywą byłoby:

select abc.client_ref_id, abc.request, def.response 
from some_table abc, 
     some_table def 
where abc.client_ref_id = def.client_ref_id 
and abc.message_type = 1 
and def.message_type = 2; 

I nie zdziwiłbym się, gdyby Oracle przepisał zapytań tak, że plan będzie taka sama w każdym razie.

+0

To rozwiązanie zajmuje tyle czasu w bazie danych, której używam. Instrukcja "abc.client_ref_id = def.client_ref_id" powoduje, że zapytanie zaczyna się od kilku sekund, aby przejąć godzinę. –

+0

Musisz bardzo uważać na czas. Czy mówisz o czasie ostatniego rzędu? lub tylko pierwsze rzędy? Niektóre plany zapytań mogą wytworzyć 1 wiersz bardzo szybko (sekundę), ale utworzenie ostatniego wiersza zajęłoby rok. Inni dostaną ostatni wiersz za minutę. –

+0

@Matt, opublikuj plan kwerendy - nie ma sensu marnować kodu SQL, gdy nie wiemy, co powoduje problem z wydajnością. –

Powiązane problemy