我在oracle中使用ROW_NUMBER函数,并试图了解当partition by和order by子句保存相同数据时它将如何表现,然后排名将如何工作(如果有重复记录)。
下面是示例数据集
select * from test
结果
Dept salary created date
HR 500 25-Jul
HR 200 25-Jul
HR 500 26-Jul
Accounts 300 25-Jan
Accounts 300 26-Jan
Accounts 300 27-Jan
我根据上面的设置运行了 row_number 函数
select *,ROW_NUMBER() OVER(partition by Dept order by salary) as row_number
from test
结果
Dept salary created date row_number
HR 500 25-Jul 1
HR 200 25-Jul 1
HR 500 26-Jul 2
Accounts 300 25-Jan 1
Accounts 300 26-Jan 2
Accounts 300 27-Jan 3
正如您在上面的输出中看到的,我使用部门作为 row_number 的分区依据,使用工资作为 row_number 的排序依据,它给了我排名 1,2,3。 我在这里试图理解的是,对于partition by和order by子句中的相同数据,oracle是否根据记录输入系统的时间分配row_number,如上面的“Accounts”“300”,它给出了row_number 1最早进入系统的记录“25-Jan”
是否有任何地方明确提到,如果它对相同数据进行分区和排序,那么将根据这些记录输入系统的时间进行排名。
我在这里试图理解的是,对于partition by和order by子句中的相同数据,oracle是否根据记录输入系统的时间分配row_number,如上面的“Accounts”“300”
不,事实并非如此。 SQL 表代表“无序”集合。 除非通过引用列值明确提供,否则没有顺序。 如果按相同的值排序,
无法保证行的顺序。 请注意,当 order by
键中有联系时,运行相同的查询两次可能会产生不同的结果。 甚至可以在同一个查询中。 对于
order by
子句和分析函数都是如此。如果您想要保证,那么您需要包含一个唯一列作为最后一个排序键(好吧,它不可能是最后一个,但它实际上是最后一个)。
SELECT T.*,ROW_NUMBER() OVER(partition by Dept order by salary, ROWID) as row_number
FROM test T