groupnum over partition

时间:2011-07-14 16:50:59

标签: sql oracle database-partitioning rownum

我有一个Oracle 11g表如下:

id  name    department
1   John    Accounting
2   Frederick   BackOffice
3   Erick   Accounting
4   Marc    BackOffice
5   William BackOffice
6   Pincton Accounting
7   Frank   Treasury
8   Vincent BackOffice
9   Jody    Security

我想查询获取所有记录的表,并为每个记录分配一个序列到部门,所以结果将是这样的:

1   John    Accounting  1
2   Frederick   BackOffice  2
3   Erick   Accounting  1
4   Marc    BackOffice  2
5   William BackOffice  2
6   Pincton Accounting  1
7   Frank   Treasury    4
8   Vincent BackOffice  2
9   Jody    Security    3

我知道我可以获取他们部门内每条记录的序列号,使用rownum over partition by ...,问题是如何在组级别执行“相同”,为每个组分配一个序列(假设订单是按部门名称,如示例所示)。有什么想法吗?

1 个答案:

答案 0 :(得分:5)

使用ALL_TABLES作为演示(“所有者”代替“部门”,“table_name”而不是“名称”),我认为dense_rank会为您提供所需内容:

SELECT owner, 
       table_name, 
       ROW_NUMBER () OVER (PARTITION BY owner ORDER BY table_name) as table_seq, 
       DENSE_RANK () OVER (ORDER BY owner) as owner_seq
FROM   all_tables

这有效的原因是dense_rank提供了所提供顺序的排名。无论哪个所有者(部门)排在第一位,都是该所有者的所有实例之间的关系,因此所有这些记录的排名均为1.由于我们使用dense_rank代替rank,所有这些关系都不会不计算增加排名,所以下一个所有者获得排名为2。


如果我正确理解您的后续问题,使用我的示例,您想显示每个所有者和每个所有者的前500个表吗?在这种情况下,您真的只想基于table_seq进行过滤,因此您必须使用子查询:

SELECT * 
FROM   (SELECT owner, 
               table_name, 
               ROW_NUMBER () OVER (PARTITION BY owner ORDER BY table_name) as table_seq, 
               DENSE_RANK () OVER (ORDER BY owner) as owner_seq
        FROM   all_tables)
WHERE  table_seq <= 500