2016-06-07 11 views
1

Ich habe eine Tabelle, die einen Datensatz für jedes Element in einem Dateisystem speichert, wobei ein Element sowohl ein Ordner als auch eine tatsächliche Datei sein kann.So begrenzen Sie die Anzahl der für jede Gruppe zurückgegebenen Zeilen

ID | Name  | Date | Parent ID 
----------------------------------- 
0 | someFolder | xxx | NULL 
1 | a.txt  | yyy | 0 
2 | b.txt  | zzz | 0 

Wenn ich also eine Ordnerstruktur haben, die so geht:

mainFolder (ID = 0) 
    folder1 
     a.txt 
     b.txt 
    folder2 
     c.txt 
     d.txt 

Und ich möchte alle Blattknoten finden, ‚zusammengebaut‘, mit welchem ​​Stammordner sie sind, benutze ich diese query:

select id, name, date, connect_by_root name as "Group" from myTable 
where connect_by_isleaf = 1 
start with parentid = 0 
connect by prior id = parentid 

was mich etwas entlang der Linien dieser Ausgabe erhält:

ID | Name | Date | Group 
--------------------------- 
3 | a.txt | xxx | folder1 
4 | b.txt | yyy | folder1 
8 | c.txt | zzz | folder2 
9 | d.txt | xyz | folder2 

Was ich tun möchte, ist die Anzahl der für jede 'Gruppe' zurückgegebenen Zeilen zu begrenzen. Zum Beispiel, wenn beide Ordner mehr als 2 Elemente hätten, würde ich nur die ersten beiden (in Bezug auf das neueste Datum) von jedem wollen. Wie würde ich das tun?

Antwort

2

Also versuche ich die row_number() -Analyse verwenden, um eine Zeile Nummer für jede Datei in einer Gruppe zuzuweisen. Beginnen Sie mit 1 bis X und verwenden Sie dann eine where-Klausel, um die row_number auf nur die 2 gewünschten Dateien zu beschränken ... Da die row_number materialisieren muss, bevor wir eine where-Klausel darauf anwenden können, muss ich einen subselect oder CTE verwenden.

nicht sicher, wie gut ein CTE und eine Verbindung nach vorheriger zusammen mit einem row_number zusammen spielt ... Mai hat 2 CTE verwenden

Ich bezweifle, ich habe die Syntax perfekt ohne Prüfung; aber das vermittelt ein allgemeines Konzept.

1. Versuch:

With CTE AS (
select id, name, date, connect_by_root name as "Group", 
ROW_NUMBER() over (partition by connect_by_root name order by ID) RN 
from myTable 
where connect_by_isleaf = 1 
start with parentid = 0 
connect by prior id = parentid) 
Select * from cte where RN <= 2 

Zweiter Versuch:

With CTE AS (
select id, name, date, connect_by_root name as "Group" from myTable 
where connect_by_isleaf = 1 
start with parentid = 0 
connect by prior id = parentid), 

CTE2 as (Select A.*, 
     Row_number() over (partition by Group order by ID) RN from CTE A) 
Select * from cte2 where RN <= 2 
+0

Beiden Abfragen am Ende arbeiten, danke! (Der erste musste nur 'von meinerTabelle' nach' RN' verschoben werden) – idlackage

+0

Korrigiert, damit ist es nach RN. Gut, mir hat das erste besser gefallen. Es bestand jedoch die Befürchtung, dass die Stammnamen für die Analyse zur Zeit der Ausführung nicht verfügbar sein könnten (Reihenfolge der Betriebsprobleme). – xQbert

Verwandte Themen