2012-04-22 4 views
19

テーブル内のデータのサブセットをランク付けしようとしていますが、私は何か間違っていると思います。私はpostgresのrank()機能に関する多くの情報を見つけることができません。おそらく、間違った場所を探しています。いずれにしても:postgresクエリのランク付け方法

私は、日付に基づいてテーブルのクラスタ内にある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である。

+3

ランクは何に比例しますか?すべてのレコード(これは上のクエリが尋ねるもので、おそらくそれが長すぎる理由です)?述語によって選択されたレコードの集合?いくつかの他のグループ化? 'over'句は、すべての行をランク付けしたくない場合には' partition by'を指定する必要があります。 [ウィンドウ関数のチュートリアルはこちら](http://www.postgresql.org/docs/8.4/static/tutorial-window.html) – dbenhur

+0

pub_dateに相対的なランクを付けたいと思います。たぶん私はもう少し説明できます:url_infoには何千ものURLがあります。それらのうち39個はクラスタ9876を包括しています。9876のメンバーであるURLだけを選択すると、pub_dateに基づいてURL(クラスタ9876を構成する)を順位付けします。このためにウィンドウ関数に基づいてパーティションを使用していますか?私はあなたが送ったURLを見ました。これは、私がここでやっていない、いくつかの値を計算した後に項目をランク付けすることを参照しているようです。 – WildBill

答えて

26

副選択にランク()関数を配置し、OVER句または任意の述語でBY PARTITIONを指定しないことでそのsubselectでは、あなたの問合せは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; 
+0

'rank()over(pub_date asc)デフォルトの列名は関数の名前なので – isapir

+0

@isapirかもしれませんが、それは強い約束ではありません。 [docs](https://www.postgresql.org/docs/current/static/sql-select.html#SQL-SELECT-LIST)から: "より複雑なケースでは、関数または型名**は* *使用されているか、システムが?columnのような生成された名前に戻ってしまう可能性があります。 – dbenhur

5

DENSE_RANK(の別の例を共有) PostgreSQLの 上位3名のサンプルクエリを検索します。 Reference taken from this blog:

サンプルデータを持つテーブルを作成します。DENSE_RANK()を使用

CREATE TABLE tbl_Students 
(
    StudID INT 
    ,StudName CHARACTER VARYING 
    ,TotalMark INT 
); 

INSERT INTO tbl_Students 
VALUES 
(1,'Anvesh',88),(2,'Neevan',78) 
,(3,'Roy',90),(4,'Mahi',88) 
,(5,'Maria',81),(6,'Jenny',90); 

、学生のRANKを計算します。

;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; 

結果:

studname | totalmark | studrank 
----------+-----------+---------- 
Roy  |  90 |  1 
Jenny |  90 |  1 
Anvesh |  88 |  2 
Mahi  |  88 |  2 
Maria |  81 |  3 
(5 rows) 
関連する問題