厦门市建设区网站首页,梅州建站多少钱,开发网站用什么语言好,国外哪些网站做产品推广比较好目录 一、背景二、定义三、实现需求 一、背景 SQL需求#xff1a; 假设有一个用户表#xff0c;我们想根据用户的部门#xff08;depart_no#xff09;进行分组#xff0c;找出每个组织中的任意一人。 在 PostgreSQL 中#xff0c;如果要实现上面这个需求#xff0c;假设… 目录 一、背景二、定义三、实现需求 一、背景 SQL需求 假设有一个用户表我们想根据用户的部门depart_no进行分组找出每个组织中的任意一人。 在 PostgreSQL 中如果要实现上面这个需求假设存在唯一主键id可能会有人想到用下面这种方式来查询
select * from t_user_info
where id in (select min(id) from t_user_info group by depart_no);首先如果使用上面这个 SQL 会导致 t_user_info 表查询两遍效率不高。
其次如果条件变一下想找出每个部门depart_no中年龄age最小的人这样的话像上面使用单个子查询方式就无法实现了因为每个部门中的最小年龄有可能是重复的。除非使用两个子查询
select * from t_user_info
where id in (select min(t1.id) from t_user_info t1 (select depart_no, min(age) age from t_user_info group by depart_no) t2where t1.depart_no t2.depart_no and t1.age t2.agegroup by t1.depart_no);这样虽然实现了但是有一个前提条件是表中必须存在唯一主键而且 三个子查询导致 SQL 的可维护性和效率进一步降低了。在生产环境上我们 严令禁止这种难以维护的 SQL 出现在我们的代码中
这时候就到了我们的主角 distinct on 上场了。 二、定义
distinct on是 PostgreSQL 中一种独特的 SQL 语法用于在一组重复的记录中选取每个分组的第一条记录。不同于普通的 distinct 关键字distinct on 允许指定某些列用于区分唯一性并且可以控制每个分组返回表中存在的任意字段不同于 group by 关键字并 不局限于只能查询、排序用于分组的字段。 注意 排序的话必须要包含用于分组的字段比如分组字段是 depart_no排序可以是 order by depart_no, age也可以是 order by age, depart_no但是必须要包含 depart_no。 基本语法如下
select distinct on (column1, column2, ...) expression1, expression2
from table_name
[where conditions]
[order by column1, column2, ...];column1, column2, ...这是用于区分唯一性的字段列表distinct on 会根据这些列找出各组的第一行。expression1, expression2, ...这是你想要查询的字段或者表达式这些数据来自根据 distinct on 中的字段去重后所对应的每组数据的第一行。table_name要查询的表名。[where conditions]可选的筛选条件用于进一步过滤数据。[order by column1, column2, ...]可选的排序条件包含但不局限于分组的字段。distinct on 的关键在于需要有一个明确的排序因为 distinct on 返回的是每个分组中按照 order by 排序后的第一条记录。 三、实现需求
现在我们再用 distinct on 来重新实现一遍我们的需求假设有一个用户表我们想根据用户的部门depart_no进行分组找出每个组织中的任意一人。
select distinct on (depart_no) * from t_user_info;一个 SQL 直接解决不需要任何子查询也不需要唯一主键。
我们再来看下问题的升级版想找出每个部门depart_no中年龄age最小的人
select distinct on (depart_no) * from t_user_info order by depart_no, age;同样非常简单非常优雅这么方便的 distinct on 你学会了吗
整理完毕完结撒花~ 参考地址
1.pgsql中distinct on的用法https://blog.csdn.net/qq_24702263/article/details/105311212