请用PARTITION解释SQL

时间:2012-03-07 09:48:55

标签: sql oracle select

有人可以解释下面的问题吗? ID不是PK,同一ID可以有多行。此查询获取最新行。

SELECT ID, SCORE, DATE_OF_SCORE FROM
(
SELECT ID, SCORE, DATE_OF_SCORE, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY DATE_OF_SCORE DESC) RN
FROM PERSON_SCORE_DETAILS
WHERE ID = 123
)
WHERE RN = 1;

2 个答案:

答案 0 :(得分:3)

ROW_NUMBER()是一个分析函数,在这种情况下,函数为每一行返回一个不同的数字。 PARTITION子句控制生成行号的窗口,ORDER BY确定该分区中行的排序。

因此,正如您所观察到的那样,内部查询为每一行生成一个数字,为​​给定ID的每次记录运行的开始重置该数字,并按反向日期顺序对它们进行排序。这意味着每个ID的最新记录的行号为1.外部查询过滤该函数的别名RN,以生成仅包含所有ID的最新记录的结果集。

分析函数与聚合函数(即GROUP BY)的不同之处在于我们可以使用它们而无需按投影中的所有列进行分区。当我们想要返回其他列时,这使它们在查询中很有用。

Oracle文档全面,在线且免费。你应该学会导航它。 Find out more about analytic functions here

答案 1 :(得分:3)

此查询为id 123选择最近date_of_score的分数。 这里的partition by子句是多余的,因为您只选择一个id。

使用聚合可以更好地处理这种类型的查询,如下所示:

select id
     , max(score) keep (dense_rank last order by date_of_score) score
     , max(date_of_score) date_of_score
  from person_score_details
 where id = 123
 group by id

甚至更简单:

select 123
     , max(score) keep (dense_rank last order by date_of_score) score
     , max(date_of_score) date_of_score
  from person_score_details
 where id = 123

的问候,
罗布。