2010-06-16 9 views
13

Gibt es eine Möglichkeit, eine Unterabfrage in Oracle geben 11g einen Aliasnamen wie:Gibt es eine Möglichkeit, eine Unterabfrage in Oracle 11g SQL mit einem Alias ​​zu versehen?

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; 

Ansonsten gibt es eine Möglichkeit, die beiden Unterabfragen auf der client_ref_id Basis zu verbinden. Ich weiß, dass es einen Self-Join gibt, aber auf der Datenbank, auf der ich arbeite, kann ein Self-Join bis zu 5 Minuten dauern (es gibt eine zusätzliche Logik in der eigentlichen Abfrage, aber ich habe festgestellt, dass der Self-Join ist.) verursacht das Problem). Die einzelnen Unterabfragen dauern nur wenige Sekunden. Die Self-Join-Abfrage sieht ungefähr so ​​aus:

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

Nur neugierig, wie gut hat die angenommene Antwort ausgeführt? – DCookie

+1

Sie haben nicht herausgefunden, dass es sich um den Self-Join handelt. Machen Sie eine identische Kopie der Tabelle, Indizes und Statistiken und sehen Sie, ob Sie das gleiche Timing erhalten. Die bessere Frage wäre gewesen: "Hilf mir, diese Abfrage abzustimmen" und habe die FULL-Abfrage und den EXPLAIN-Plan gepostet. –

Antwort

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

Wie lautet der Fachbegriff für den Teil "WITH abc as (select ...)"? Wenn man nach seinen Fähigkeiten forschen wollte. – SeaBass

+2

@SeaBass: Gemeinsame Tabellenausdrücke, häufig abgekürzt als CTE (wird auch häufig als Name/Alias ​​verwendet, obwohl ich dies diesmal nicht tue). Beachten Sie, dass beide "Tabellen" als Teil des CTE hätten gemacht werden können, ich wollte nur beide Optionen zeigen, so auch die eine und die andere. – jmoreno

5

ich mit keiner Oracle-Instanz zu testen, aber was sollte man gültige ANSI-89 JOIN-Syntax sein geschrieben. Hier ist es in 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

Ihre Abfrage sollte in Ordnung sein.

Eine Alternative wäre:

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; 

würde ich nicht überrascht, wenn Oracle die Abfragen neu geschrieben, so dass der Plan ohnehin gleich sein würde.

+0

Diese Lösung dauert so lange in der Datenbank, die ich verwende. Die Anweisung 'abc.client_ref_id = def.client_ref_id' bewirkt, dass die Abfrage einige Sekunden dauert und eine Stunde dauert. –

+0

Sie müssen beim Timing sehr vorsichtig sein. Sprechen Sie über das Timing der letzten Reihe? oder nur erste Zeilen? Bestimmte Abfragepläne können 1 Reihe sehr schnell (eine Sekunde) erzeugen, aber ein Jahr dauern, um die letzte Reihe zu produzieren. Während andere die letzte Reihe in einer Minute bekommen würden. –

+0

@Matt, posten Sie den Abfrageplan - es ist nicht gut, mit dem SQL herumzuspielen, wenn wir nicht wissen, was das Leistungsproblem verursacht. –