ORDER BY 子句中的“排名”值?

eda*_*vis 5 postgresql window-functions

我有下表:

                                     Table "public.employee_employee"
     Column      |         Type          |                           Modifiers                            
-----------------+-----------------------+----------------------------------------------------------------
 id              | integer               | not null default nextval('employee_employee_id_seq'::regclass)
 name            | text                  | not null
 slug            | character varying(50) | not null
 title           | text                  | not null
 base            | numeric(10,2)         | 
 gross           | numeric(10,2)         | 
 overtime        | numeric(10,2)         | 
 benefits        | numeric(10,2)         | 
 total           | numeric(10,2)         | 
 other           | numeric(10,2)         | 
 year            | smallint              | not null
 jurisdiction_id | integer               | not null
 notes           | text                  | 
Indexes:
    "employee_employee_pkey" PRIMARY KEY, btree (id)
    "employee_employee_jurisdiction_id" btree (jurisdiction_id)
    "employee_employee_slug" btree (slug)
    "employee_employee_slug_like" btree (slug varchar_pattern_ops)
    "employee_name_title_idx" gin (to_tsvector('english'::regconfig, (name || ' '::text) || title))
Check constraints:
    "employee_employee_year_check" CHECK (year >= 0)
Foreign-key constraints:
    "jurisdiction_id_refs_id_9e093e72" FOREIGN KEY (jurisdiction_id) REFERENCES jurisdiction_jurisdiction(id) DEFERRABLE INITIALLY DEFERRED
Run Code Online (Sandbox Code Playgroud)

下面是一些在模拟数据的简化样本idjurisdiction_idyear,和total列:

1 | 1 | 2014 | 100.00
2 | 1 | 2012 | 105.00
3 | 1 | 2011 | 110.00
4 | 2 | 2013 | 115.00
5 | 2 | 2012 | 120.00
6 | 2 | 2011 | 125.00
7 | 3 | 2012 | 130.00
8 | 3 | 2011 | 135.00
9 | 4 | 2011 | 140.00
Run Code Online (Sandbox Code Playgroud)

或者,以另一种方式表示,每个唯一jurisdiction_id的年份值如下:

1: 2014, 2012, 2011
2: 2013, 2012, 2011
3: 2012, 2011
4: 2011

我想通过以下方式对这些值进行“排名”:

(1, 2014), (2, 2013), (3, 2012), (4, 2011) 将排名第一。
(1, 2012), (2, 2012), (3, 2011) 将排名第二。
(1, 2011), (2, 2011) 将排名第三。

然后,在每个等级内,行将按 排序total DESC

这是SELECT (id, jurisdiction_id, year, total) ...我正在寻找的“ ”输出(每个等级之间有换行符):

9 | 4 | 2011 | 140.00
7 | 3 | 2012 | 130.00
4 | 2 | 2013 | 115.00
1 | 1 | 2014 | 100.00

8 | 3 | 2011 | 135.00
5 | 2 | 2012 | 120.00
2 | 1 | 2012 | 105.00

6 | 2 | 2011 | 125.00
3 | 1 | 2011 | 110.00
Run Code Online (Sandbox Code Playgroud)

我不得不认为这在 PostgreSQL 中是可行的,但我什至不知道我想要做什么的正确“术语”,所以谷歌搜索有点困难。

r.m*_*r.m 5

select 
rank() over (partition by jurisdiction_id order by year desc) AS rank,
*
from your_table
order by rank,total desc;
Run Code Online (Sandbox Code Playgroud)

rank() over (...)是一个窗口函数,参见:postgresql 中的窗口函数