如何限制为每个组返回的行数

时间:2016-06-07 16:59:20

标签: sql oracle

我有一个表,它为文件系统中的每个项目存储一条记录,其中一个项目既可以是文件夹,也可以是实际文件。

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

所以如果我有一个像这样的文件夹结构:

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

我想找到所有叶节点,按照它们所在的根文件夹“分组”,我使用此查询:

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

这让我得到了与此输出相关的内容:

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

我想要做的是限制为每个“组”返回的行数。例如,即使两个文件夹都有超过2个项目,我也只想要每个文件夹中的前两个(就最近的日期而言)。我该怎么做?

1 个答案:

答案 0 :(得分:2)

因此,我尝试使用row_number()分析为组中的每个文件分配行号。从1开始到X然后使用where子句将row_number限制为只需要2个文件...因为row_number必须在我们可以应用where子句之前实现,所以我需要使用subselect或CTE。

不确定CTE和之前连接的行与row_number的结合程度如何...可能必须使用2个CTE'

我怀疑没有测试我的语法是否完美;但这传达了一个普遍的概念。

第一次尝试:

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

第二次尝试:

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