2016-10-18 4 views
2

私は30行のテーブルteamsを持っており、いくつかの統計情報が属性として格納されています。たとえば、目標、目標など、私はrank()を使用してレコードをランク​​付けする良い仕事をするビューを作成しました。私はランクがタイであるかどうかに基づいてブール値を返します追加の列を追加したいと思いPostgresqlのランク()の関係を説明する方法

SELECT name, 
    points, 
    rank() OVER (ORDER BY points DESC) AS point_tank 
FROM teams; 


     name   | points | point_rank 
-----------------------+-----------+---------------- 
Team 1    |  14 |    1 
Team 2    |  11 |    2 
Team 3    |   9 |    3 
Team 4    |   9 |    3 

:ここでは要約クエリの例と結果のテーブルです。この例ではチーム3とチーム4です。

  name   | points | point_rank  | tie 
-----------------------+-----------+----------------+---------------- 
Team 1    |  14 |    1 |   false 
Team 2    |  11 |    2 |   false 
Team 3    |   9 |    3 |   true 
Team 4    |   9 |    3 |   true 

ここのアイデアは何ですか?あるいは、私はこれを間違って近づけてランク()を乱用していますか?前もって感謝します!

一つのオプションは、共通テーブル式にあなたの現在のクエリを配置し、ランクを識別するためにそれを使用することです

答えて

3

あなたはCTEを使用し、その後に遅れ/リード機能を使用することができますネクタイをチェック:

with ranked as (
    SELECT name, 
     points, 
     rank() OVER (ORDER BY points DESC) AS point_rank 
    FROM teams 
) 
select name, points, point_rank, 
     ( point_rank = lag(point_rank, 1, -1::bigint) over (order by point_rank) 
     or point_rank = lead(point_rank, 1, -1::bigint) over (order by point_rank) 
     ) as is_tie 
from ranked; 

ラグとリード機能のデフォルト値は、そこにnullをチェック避けるために、最初と最後の行のために必要とされています。

例:http://rextester.com/SCLH63446

+0

おかげで、これは働いていたし、それは私がよりよいCTEを理解して助けました。 –

2

が重複している:

WITH cte AS (
    SELECT name, 
      points, 
      rank() OVER (ORDER BY points DESC) AS point_rank 
    FROM teams; 
) 

SELECT cte.name, 
     cte.points, 
     cte.point_rank 
     CASE WHEN t.point_rank IS NOT NULL THEN 'false' ELSE 'true' END AS tie 
FROM cte 
LEFT JOIN 
(
    SELECT point_rank 
    FROM cte 
    GROUP BY point_rank 
    HAVING COUNT(*) = 1 
) t 
    ON cte.point_rank = t.point_rank 
0
SELECT name 
    , points 
    , rank() OVER (rrr) AS point_rank 
    -- , count(*) OVER (ppp) AS ppp_cnt 
    , rank() OVER (pp2) AS sub_rank 
    , (COUNT(*) OVER (ppp) > 1) AS is_tie 
FROM teams 
WINDOW ppp AS (PARTITION BY points) 
     , pp2 AS (PARTITION BY points ORDER BY ctid) 
     , rrr AS (ORDER BY points DESC) 
ORDER BY points DESC 
     ; 

結果(私は2つの余分な行を追加):


DROP SCHEMA 
CREATE SCHEMA 
SET 
CREATE TABLE 
INSERT 0 6 
    name | points | point_rank | sub_rank | is_tie 
--------+--------+------------+----------+-------- 
Team_1 |  14 |   1 |  1 | f 
Team_2 |  11 |   2 |  1 | f 
Team_3 |  9 |   3 |  1 | t 
Team_4 |  9 |   3 |  2 | t 
Team_5 |  5 |   5 |  1 | t 
Team_6 |  5 |   5 |  2 | t 
(6 rows) 
+0

'ORDER BY ctid'は、行が更新されたときにctidが変更され、HOTアップデートが使用できないように思われます。 –

+0

はい、それは怪しいですが、安定しているとは思われません。 "sub_rank"への結びつき。ただし、代わりにチーム名または番号、または購読日を使用することができます。 – joop

関連する問題