参考:

https://stackoverflow.com/questions/27415706/postgresql-select-top-three-in-each-group

http://charlesnagy.info/it/postgresql/group-by-limit-per-group-in-postgresql

但实在看不懂这里面LATERAL的用法,而且语法和pg11似乎也有了区别。

这个里面的LATERAL用法倒是看懂了,把LATERAL当成foreach来用:

https://www.oschina.net/translate/postgresqls-powerful-new-join-type-lateral?cmp

简单说,用LATERAL JOIN2个子查询:

1 GROUP BY 得到聚合后的分组

2 再用这个数量缩水的 用WHERE inner.grp = outer.grp 去过滤没缩水前的全部数据。排序得到查询结果

最终外面再包1层select

——但如果inner是个view 等于里面要扫描N次 N等于1的group数量。

我的分组有点多,几百个,实测结果:要5秒钟,实在不能忍,性能太差了

最后,还是用https://stackoverflow.com/questions/27415706/postgresql-select-top-three-in-each-group

里面最直接的窗口函数法,1次FROM就搞定,400ms,就算凑合了

SELECT *
FROM(
SELECT *
,ROW_NUMBER() OVER (PARTITION BY grp
ORDER BY value DESC) AS order_in_grp
FROM table1
) AS A
WHERE order_in_grp < 2

子查询里用窗口函数得到每个分组内的序号order_in_grp:按grp字段分组,组内按value降序的序号

外层只是用WHERE过滤出每个组内前1名。

对我这种新手来说,还是这样简单、直接、标准语法的方式更适合我。怎么用LATERAL才能效率高,暂时无暇顾及了。

起码符合The Zen of Python的前几条

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.

心得

不是看见分组就一定要GROUP BY, 窗口函数这样反而更灵活——不聚合,而是,在子查询里给出组内排名order_in_grp字段,然后在外面做1次WHERE把每个分组的前N名过滤出来。

postgres select TOP X in group 查询每个组的前几名的更多相关文章

  1. 如何在MySQL中查询每个分组的前几名【转】

    问题 在工作中常会遇到将数据分组排序的问题,如在考试成绩中,找出每个班级的前五名等. 在orcale等数据库中可以使用partition语句来解决,但在mysql中就比较麻烦了.这次翻译的文章就是专门 ...

  2. 如何在mysql中查询每个分组的前几名

    问题 在工作中常会遇到将数据分组排序的问题,如在考试成绩中,找出每个班级的前五名等.  在orcale等数据库中可以使用partition 语句来解决,但在MySQL中就比较麻烦了.这次翻译的文章就是 ...

  3. mysql 查询每个分组的前几名

    按分组排序,并查出每个分组的前3名 单表 SELECT * FROM ( SELECT ZONEID, uid, NAME, fight, IF ( , ) AS rank, ( @zone := z ...

  4. mysql查询每个部门/班级前几名

    Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id . +----+-------+--------+--------------+ | I ...

  5. SQL使用开窗函数与CTE查询每月销售额的前几名

    WITH tagTab AS( SELECT YearMonth, pm=RANK() OVER(PARTITION BY YearMonth ORDER BY amount DESC) FROM S ...

  6. mysql 查询每个班级成绩前两名

  7. 查询出各个学科的前3名的同学信息的Sql

    查找各个学科的成绩前3名的学生信息Sql,有2种方法,一种是利用sql的row_number() over()函数,另一种是用子查询, 表设计如下 如果不考虑各个学科的成绩有并列的情况的话,有如下两种 ...

  8. 数据库学习笔记3 基本的查询流 2 select lastname+','+firstname as fullname order by lastname+','+firstname len() left() stuff() percent , select top(3) with ties

    数据库学习笔记3 基本的查询流 2   order by子句对查询结果集进行排序 多列和拼接 多列的方式就很简单了 select firstname,lastname from person.pers ...

  9. Solr --- Group查询与Facet区别

    简介 facet的查询结果主要是分组信息:有什么分组,每个分组包括多少记录:但是分组中有哪些数据是不可知道的,只有进一步搜索. group则类似于关系数据库的group by,可以用于一个或者几个字段 ...

随机推荐

  1. CF140C New Year Snowmen(贪心+优先队列)

    CF140C 贪心+优先队列 贪心策略:每次取出数量最多的三种球,合成一个答案,再把雪球数都-1再插回去,只要还剩下三种雪球就可以不断地合成 雪球数用优先队列维护 #include <bits/ ...

  2. 牛客小白月赛13-H(单调栈+树状数组)

    题目链接:https://ac.nowcoder.com/acm/contest/549/H 题意:给一个柱状图,包括每个矩阵的宽度和高度,求能组成的最大矩阵的面积. 思路:显然最大矩阵的高一定为n个 ...

  3. zookeeper集群的搭建(CentOS 7)

    注意ip地址为: 虚拟机ip设置 TYPE="Ethernet"BOOTPROTO="static"NAME="enp0s3"DEVICE= ...

  4. 洛谷 P3919 可持久化线段树 题解

    题面 这题好水的说~很明显就是主席树的大板子 然而我交了3遍才调完所有的BUG,开好足够的数组,卡掉大大的常数: 针对与每次操作,change()会创建新节点,而ask()虽然也会更新左右儿子的节点编 ...

  5. 带EFI支持的GRUB2安装全记录

    版权归作者所有,任何形式转载请联系作者. 作者:keenshoes(来自豆瓣) 来源:https://www.douban.com/note/210077866/  关键词:EFIGRUB2efibo ...

  6. sql server 函数详解(1)字符串函数

    ASCII()函数 CHAR()函数 LEFT()函数 RIGHT()函数 LTRIM()函数 RTRIM()函数 STR()函数 字符串逆序的函数REVERSE() 计算字符串的长度函数LEN(st ...

  7. Vue组件学习(转载)

    什么是组件:组件是Vue.js最强大的功能之一.组件可以扩展HTML元素,封装可重用的代码.在较高层面上,组件是自定义的元素,Vue.js的编译器为它添加特殊功能.在有些情况下,组件也可以是原生HTM ...

  8. synchronize和lock的区别 & synchionzie与volatile的区别

    synchronized与Lock的区别 https://www.cnblogs.com/iyyy/p/7993788.html Lock和synchronized和volatile的区别和使用 ht ...

  9. Java读取二进制文件的方式

    public static void readFile(String fileName){ File file = new File(fileName); if(file.exists()){ try ...

  10. ACM常用之 异或运算的性质。