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;