29

テーブル内のデータのサブセットをランク付けしようとしていますが、何か間違っていると思います。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

私が何か間違ったことをしていると思う理由は、cluster_id 9876 にある url_info に 39 行しかなく、このクエリが 10 分間実行され、戻ってこなかったからです。(実際にはかなりの時間再実行しましたが、結果は返されませんでしたが、クラスター9876にID 1234の行があります)これにより、「ID 1234は指定された基準で5番目でした」のようなことがわかると思います)。は、クエリの制約に従って相対的なランクを返しますよね?

これはpostgres 8.4 btwです。

4

2 に答える 2

42

サブセレクトに rank() 関数を配置し、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;
于 2012-04-22T09:19:53.017 に答える