如何在postgres查询中排名

时间:2012-04-22 04:31:02

标签: postgresql

我正在尝试对表中的数据子集进行排名,但我认为我做错了。我找不到关于postgres的rank()功能的很多信息,也许我在找错了地方。无论哪种方式:

我想知道基于日期的属于表的集群中的id的等级。我的查询如下:

select cluster_id,feed_id,pub_date,rank 
from (select feed_id,pub_date,cluster_id,rank() 
    over (order by pub_date asc) from url_info) 
as bar where cluster_id = 9876 and feed_id = 1234;

我正在对以下stackoverflow帖子进行建模:postgres rank

我认为我做错了什么的原因是url_info中只有39行在cluster_id 9876中,这个查询运行了10分钟而且从未回来过。 (实际上重新运行了很长一段时间并且它没有返回结果,但是在集群9876中有一行用于id 1234)我希望这会告诉我“id 1234对于给出的标准是第5位”。会根据我的查询约束返回相对排名,对吗?

这是postgres 8.4顺便说一句。

2 个答案:

答案 0 :(得分:32)

通过将rank()函数放在subselect中而不在over子句或该子选择中的任何谓词中指定PARTITION BY,您的查询要求在pub_date排序的整个url_info表上生成排名。这可能是为什么它只要排在所有url_info之上,Pg必须按pub_date对整个表进行排序,如果表格非常大,则需要一段时间。

您似乎只想为where子句选择的记录集生成排名,在这种情况下,您只需要消除子选择,并且排名函数隐含在匹配该谓词的记录集上。

select 
  cluster_id
 ,feed_id
 ,pub_date
 ,rank() over (order by pub_date asc) as rank
from url_info
where cluster_id = 9876 and feed_id = 1234;

如果你真正想要的是群集中的排名,无论feed_id如何,你都可以在一个过滤到该群集的子选择中排名:

select ranked.*
from (
  select 
    cluster_id
   ,feed_id
   ,pub_date
   ,rank() over (order by pub_date asc) as rank
  from url_info
  where cluster_id = 9876
) as ranked
where feed_id = 1234;

答案 1 :(得分:7)

分享PostgreSQL的DENSE_RANK()的另一个例子。 查找前3名学生样本查询。 Reference taken from this blog:

创建包含示例数据的表格

;WITH cteStud AS
(
    SELECT 
        StudName
        ,Totalmark
        ,DENSE_RANK() OVER (ORDER BY TotalMark DESC) AS StudRank
    FROM tbl_Students
)
SELECT 
    StudName
    ,Totalmark
    ,StudRank
FROM cteStud 
WHERE StudRank <= 3;

使用DENSE_RANK(),计算学生成绩:

studname | totalmark | studrank
----------+-----------+----------
 Roy      |        90 |        1
 Jenny    |        90 |        1
 Anvesh   |        88 |        2
 Mahi     |        88 |        2
 Maria    |        81 |        3
(5 rows)

结果:

<DetokenizeVsixManifestSource
  InputFile="@(SourceVsixManifest)"
  OutputFile="$(IntermediateVsixManifest)"
  ResolvedReferences="@(_VsixManifestResolvedReferences)">
  <Output TaskParameter="OutputFile" ItemName="FileWrites" />
</DetokenizeVsixManifestSource>