2016-05-03 10 views
0

Ich bin mir nicht sicher, ob es elegantere Art und Weise ist das als vom Benutzer zu lösen, und rownum (in Oracle), aber hier geht:mit mehreren Aggregatfunktion basierten einer Zeile auswählen Bedingungen ohne Unterabfrage

Ich habe diese Tabelle (genannt Gewinner):

Name  Salary  House Kids 
-------------------------------- 
Barabara 2500.00 40  4 
Dale  2000.00 60  3 
Aaron 2000.00 45  2 
Joe  2000.00 45  4 
Jacob 2000.00 50  4 
Melissa 2500.00 50  4 

Haus bedeutet Hausgröße in qm.

Ich brauche eine Abfrage (ohne Unterabfrage), die einen "Gewinner" finden wird (der Name, aber die Zeile kann mit mehr Spalten sein). der „Gewinner“ ist wie so definiert:

  • verdient das niedrigste Gehalt
  • (im Fall der Bindung :) hat das kleinste Haus
  • (bei einer anderen Bindung :) hat die größte Anzahl von Kindern .

In diesem Beispiel ist der Gewinner Joe die 2000 verdient, hat Hausgröße von 45 und hat vier Kinder.

Der einzige Weg, (die mit den Indizes nur einen sehr einfachen, aber effizienten Code hat, und hat immer noch eine Art von Unterabfrage (Inline), hat also eine anderes wählt) ist:

select * 
from 
    (select name 
    from winner 
    order by salary, house, kids desc) 
where rownum = 1; 

Gibt es eine andere Art und Weise zu Tun Sie dies ohne Unterabfrage? (vielleicht Aggregatfunktionen?)

+0

werden Sie eine "Join" betrachten? – Bulat

+0

Dies ist der Standard Weg, um Ihr Problem zu lösen. Warum brauchen Sie eine Abfrage * ohne Unterabfrage *? – mathguy

+0

ist es eine Aufgabe. könnte ich eine "Join" betrachten. Denkst du, es ist der einzige Weg? – Neer

Antwort

1

In früheren Versionen von Oracle, Sie keep verwenden können:

select max(name) keep (dense_rank first order by salary, house, kids desc) as name, 
     max(salary) keep (dense_rank first order by salary, house, kids desc) as name, 
     max(house) keep (dense_rank first order by salary, house, kids desc) as name, 
     max(kids) keep (dense_rank first order by salary, house, kids desc) as name 
from rownum_order_test; 

Wenn Sie Bindungen möchten, Sie können auch versuchen:

select listagg(name, ',') keep (dense_rank first order by salary, house, kids desc) as names 
from rownum_order_test; 

Dieses Konstrukt kann sehr nützlich sein, wenn mit korrelierten Unterabfragen gearbeitet wird, da Scoping für Korrelationsklauseln in Oracle begrenzt ist. Beachten Sie, dass beim Einholen der Werte

Wie von Bulat erwähnt, gibt es auch eine bessere Methode in Oracle 12c + mit fetch first 1 row only. Und es gibt eine andere Methode, die first_value() und select distinct verwendet. Keine von beiden bietet eine Lösung für Bindungen.

+0

Der erste funktioniert (wird 11g schon als _earlier_ Versionen betrachtet? :-)) – Neer

Verwandte Themen