HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlMinor

"Ranking" values in an ORDER BY clause?

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
rankingclauseordervalues

Problem

I have the following table:

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


Here's a simplified sample of some mock data for the id, jurisdiction_id, year, and total columns:

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


Or, presented another way, each unique jurisdiction_id has the following year values:

1: 2014, 2012, 2011

2: 2013, 2012, 2011

3: 2012, 2011

4: 2011

Solution

select 
rank() over (partition by jurisdiction_id order by year desc) AS rank,
*
from your_table
order by rank,total desc;


rank() over (...) is a window function, see: window functions in postgresql

Code Snippets

select 
rank() over (partition by jurisdiction_id order by year desc) AS rank,
*
from your_table
order by rank,total desc;

Context

StackExchange Database Administrators Q#60876, answer score: 5

Revisions (0)

No revisions yet.