postgre dinstinct on()的使用

意思是DISTINCT ON ( expression [, …] )把记录根据[, …]的值进行分组,分组之后仅返回每一组的第一行。 
需要注意的是,如果你不指定ORDER BY子句,返回的第一条的不确定的。如果你使用了ORDER BY 子句, 
那么[, …]里面的值必须靠近ORDER BY子句的最左边。
postgres=# CREATE TABLE score_ranking (id int, name text, subject text, score numeric);

postgres=# INSERT INTO score_ranking VALUES (1,'killerbee','数学',99.5), (2,'killerbee','语文',89.5),(3,'killerbee','英语',79.5), (4,'killerbee','物理',99.5), (5,'killerbee','化学',98.5),(6,'刘德华','数学',89.5), (7,'刘德华','语文',99.5), (8,'刘德华','英语',79.5),(9,'刘德华','物理',89.5), (10,'刘德华','化学',69.5),(11,'张学友','数学',89.5), (12,'张学友','语文',91.5), (13,'张学友','英语',92.5),(14,'张学友','物理',93.5), (15,'张学友','化学',94.5);
//先查看下当前表的内容。
postgres=# select * from score_ranking ;
 id |   name    | subject | score 
----+-----------+---------+-------
  1 | killerbee | 数学    |  99.5
  2 | killerbee | 语文    |  89.5
  3 | killerbee | 英语    |  79.5
  4 | killerbee | 物理    |  99.5
  5 | killerbee | 化学    |  98.5
  6 | 刘德华    | 数学    |  89.5
  7 | 刘德华    | 语文    |  99.5
  8 | 刘德华    | 英语    |  79.5
  9 | 刘德华    | 物理    |  89.5
 10 | 刘德华    | 化学    |  69.5
 11 | 张学友    | 数学    |  89.5
 12 | 张学友    | 语文    |  91.5
 13 | 张学友    | 英语    |  92.5
 14 | 张学友    | 物理    |  93.5
 15 | 张学友    | 化学    |  94.5
(15 rows)

//以下就是 distict on 的用法:
//取出每门课程的第一名.
postgres=# select distinct on (subject) id,name,subject,score 
from score_ranking
order by subject,score desc; 备注:逻辑是: 先依据subject进行分组,比如如果subject有五类,那就分成5组。其次,score desc决定每一组内部排序,最终决定每组取谁。 id | name | subject | score ----+-----------+---------+------- 5 | killerbee | 化学 | 98.5 1 | killerbee | 数学 | 99.5 4 | killerbee | 物理 | 99.5 13 | 张学友 | 英语 | 92.5 7 | 刘德华 | 语文 | 99.5 (5 rows)

order by的时候,按照上面的说法

"如果你使用了ORDER BY 子句, 那么[, …]里面的值必须靠近ORDER BY子句的最左边。"
select distinct on (subject),所以根据分数排序的时候,本来应该是order by score,而[, …]里面的值(subject)必须靠近ORDER BY子句的最左边,
所以是 order by subject,score desc;