2010-11-27 6 views
1

Ich habe eine gespeicherte Prozedur, die einen Cursor zurückgibt.Oracle Pl/SQL geben einen Cursor aus mehreren Abfragen

Die Anwendung übergibt einen Parameter an die Prozedur, die festlegt, wie viele IDs abgerufen werden sollen, so dass die Prozedur einen Kopf der Zeit dieser Nummer nicht kennt.

foreach ID Ich muss die oberen 3 Datensätze mit dieser ID abrufen. , was ich versucht habe, ist mit:

select * from table_name where id in (List of ID`s); 

Diese Abfrage funktioniert, aber ich kann nicht die Top-3 jeder ID erhalten. Wenn ich die Anzahl der Ergebnisse limitiere, bekomme ich die TOP-Ergebnisse der ersten ID.

Ich dachte mit For Loop, Ausführen der Abfrage für jede ID und fügen Sie die Ergebnisse an den Cursor, aber wie ich es verstehe, ist es unmöglich.

Irgendwelche Ideen?

Weitere Details Lets sagen, ich habe 5 ID s and each of them have inner Id s so Id 1 hat (1,2,3,4,5) Id 2 (1,2,3,4,5) Id 3 (12,14,15,16,22) Id 4 (2,3,5,7,9) Id 5 (4,7,8,9,10) In diesem Fall, mit dem ich es zu tun habe Ich sehe nicht, wie die Zeilennummer mir helfen wird. Ich brauche die oberen 3 für jede ID, in diesem Fall sollte der Cursor 15 Ergebnisse haben.

10x viel und ein gutes Wochenende haben;)

Antwort

5

Vermutlich haben Sie einige Kriterien für die ersten drei zu bestimmen?

Wie auch immer, der Weg zu diesem Ziel ist mit einer analytischen Funktion. Oracle bietet drei verschiedene Funktionen: ROW_NUMBER(), RANK() und DENSE_RANK(). Diese bieten drei leicht unterschiedliche Interpretationen von TOP 3. Find out more.

Hier ist die Grundidee, mit ROW_NUMBER(), die genau drei Zeilen für jede ID zurückgibt.

open rc for 
    select * from (
     select t.* 
       , row_number() over (partition by id order by whatever) rn 
     from table_name t 
     where t.id in (List of ID`s) 
    ) 
    where rn <= 3; 

Die whatever im ROW_NUMBER() Klausel ist die Spalte, die Sie TOP-ness bestimmen verwenden.

+0

Ich habe eine Möglichkeit, die Top 3 für jede ID der ID einzeln zu bestimmen. –

+0

@Udi l: Das ist, was der 'PARTITION BY'-Teil einer analytischen/Ranking/Windowing-Funktion tut (in diesem Fall ROW_NUMBER). –

+0

Ihre Lösung funktioniert perfekt, genau das, was ich brauchte. 10x viel. –

-2

Eine weitere Idee, mit zu gehen wäre eine Oracle temporäre Tabelle

create global temporary table temp_table_name 

Link to more information

Dann in einer for-Schleife definieren Sie die Zeilen in der temporären Tabelle für alle benötigten IDs einfügen können. Der zurückgegebene Cursor wäre dann der Inhalt der temporären Tabelle. Natürlich macht diese Lösung nur Sinn, wenn es nicht möglich ist, das Ergebnis von einer einzigen SQL-Abfrage zurück zu bekommen.

+0

Ich möchte betonen, dass die Leistung für diese Abfrage kritisch ist und auf dem schnellsten Weg ausgeführt werden soll. 10x :) –

+1

Nun ist es durchaus möglich, das Ergebnis von einer einzigen Abfrage zurück zu bekommen, so dass eine globale temporäre Tabelle einen unnötigen Overhead darstellt. – APC

Verwandte Themen