# Oracle: Anzahl Datensätze beschränken



## rownum (6. Mai 2010)

Hallo zusammen,

stellt Euch eine Tabelle1 vor die nur ein Feld enthält. Dieses Feld enthält 51 unterschiedliche Benutzernamen.
In der selben DB gibt es eine Tabelle2 die zu jedem Benutzernamen Transaktionsdaten mit Transaktionszeitpunkt enthält.
Über einen Join zwischen den Feldern Benutzername sollen die Transaktionsdaten zu den 51 Benutzern selectiert werden.

Soweit ist das ja kein Problem. Problematisch wird das Vorhaben wenn je Benutzer in Tabelle1 aus Tabelle2 nur die 10
letzten (jüngsten ) Transaktionen zurückgegeben werden sollen.

Hat hier jemand einen Lösungsvorschlag für mich ?

Gruß
 rownum


----------



## Yaslaw (6. Mai 2010)

Dein Name ist Programm, ROWNUM

Mach ein sortiertes SELECT und selektioniere von dem alles was ROWNUM < 11 hat....


----------



## rownum (6. Mai 2010)

Hallo yaslaw,

das ging ja fix  danke.
Leider habe ich noch keinen Plan wie ich das mit Deinem Vorschlag umsetzen kann.

Mache ich ein 

ORDER BY Tabelle2.Benutzername, Tabelle2.Transaktionszeitpunkt DESC

und beschränke mit 

ROWNUM < 11

die Anzahl der Daten auf 10, erhalte ich vll. von einem Benutzer die 10 aktuellesten Transaktionen
oder wenn der erste sortierte Benutzer nur 3 Transaktionen im Bestand hat vom nächsten Benutzer 
noch 7 aktuelle Transaktionen.

Gruß
 rownum


----------



## Yaslaw (6. Mai 2010)

Hm.. Stimmt.
Oh, wie lange hab ich schon kein ORacle-SQL mehr gemacht......


----------



## rownum (7. Mai 2010)

Hallo zusammen,

hier noch ein Versuch das Abfrage-Problem etwas verständlicher zu beschreiben.

Eine Tabelle enthält ca. 5000 Transaktionsdaten von 51 Benutzern.
In der Tabelle ist das Feld Benutzerame (Inhalt z.B. Hugo) und das Feld Transaktionszeitpunkt (Inhalt z.B. 01.05.2010 12:45:53).
Über eine Abfrage (evtl. auch verschachtelt) möchte ich von jedem Benutzer die 10 letzten Transaktionen erhalten.

Gruß
 rownum


----------



## MPr (7. Mai 2010)

Hallo,

hört sich nach einem Fall für analytische Funktionen an, also etwas sein wie:


```
select t.username
     , r.object_name
     , r.rownumber
  from (select owner
             , object_name
             , created
             , row_number() over(partition by owner order by created) rownumber
          from dba_objects ) r
     , dba_users t
 where t.username = r.owner
   and r.rownumber <= 10
 order by t.username
        , r.rownumber
```

Gruß

MP


----------



## rownum (9. Mai 2010)

Hallo MP,

oha, analytische Funktionen, das hört sich schon mal vielversprechend an.
Besten Dank schon mal.
Da ich momentan nicht testen kann habe ich vorab noch eine Frage. 

Gehe ich recht in der Annahme, dass das SQL auf dem Thread-Beginn mit zwei 
Tabellen basiert ?

Falls ja müsste 

dba_users     = Tabelle1
dba_objects  = Tabelle2
username      = Benutzername
owner             = Benutzername
created           = Transaktionszeitpunkt
object_name = dba_objects.Transaktionsdaten

und

where t.username = r.owner
müsste der Join sein.

Gruß
 rownum


----------



## MPr (9. Mai 2010)

ja, das war für die Variante mit 2 Tabellen; und auch die Zuordnung der Spalten ist korrekt. Für die Version mit nur einer Tabelle vereinfacht sich die Lösung insofern als dann natürlich kein Join erforderlich ist; dann benötigt man nur noch die Nummerierung in einer inneren Query und die Filterung auf die letzten 10 Transaktionen pro Benutzer in einer äußeren Query (weil man analytics nicht in der WHERE-clause verwenden kann)

Gruß

MP


----------



## rownum (14. Mai 2010)

Hallo MP,

das ist ja sensationell !  
Nach dem Anpassen des SQL an die realen Tabellen erhielt ich über die Abfrage das korrekte Ergebnis.
Echt genial.
Vielen Dank für die professionelle Hilfe.

Viele Grüße
 rownum


----------

