PostgreSQL 使用 JOIN + GROUP BY + HAVING 查找拥有多条关联记录的数据行
文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载本篇技术指南讲解 PostgreSQL 中一个高频实战场景在 one-to-many一对多表关联下如何通过join、group by与having三者的组合筛选出拥有多条关联记录的父表记录。以authors作者与books书籍为例读完你可以掌握一条可直接复制运行、并能在多种业务场景查重复、按类型统计、过滤聚合结果中举一反三的查询范式。一对多关联与本题的查询目标关系型数据库中最常见的表关联形态之一就是 one-to-many 关系。典型例子一个书架数据库里存在authors表每位作者可以关联多条books表中的记录。这条关系通过books表上的author_id外键列体现它指向authors.id。这种结构的建表方式与本仓库中 add-foreign-key-constraint-without-a-full-lock.md 展示的外键定义一脉相承alter table books add constraint fk_books_authors foreign key (author_id) references authors(id) not valid;需求随之而来如何找出那些不是 0 本、也不是 1 本而是拥有多本书的作者答案是先做 join再在聚合结果上追加一个having子句。核心查询join group by having直接给出可运行的查询select authors.id, authors.name, count(books.id) from authors join books on authors.id books.author_id group by authors.id having count(books.id) 2;这条查询会返回所有拥有 ≥ 2 本书的作者每一行包含作者 id、作者姓名以及他名下的书籍数量count。执行思路分三步join books 到 authors把书籍与作者按外键authors.id books.author_id连接起来得到每位作者 × 他的每一本书的宽表group by authors.id按作者 id 分组产出每位作者唯一的一组记录count 聚合用count(books.id)把每组内的多本书聚合成一个数字——注意books.id是主键、非空因此它比count(*)更精确地反映书的数量。最后一步是关键having子句之所以必要是因为它是我们在 SQL 中对聚合值aggregate进行过滤的手段。普通的where在分组发生前逐行过滤而这里要过滤的是聚合计算出来的结果只能交给having。为什么是 having 而不是 wherewhere与having的执行时序不同where在group by之前、针对每一行原始记录求值having在group by与聚合计算之后、针对每一组求值。因此count(books.id) 2这类涉及聚合函数的条件必须写在having中。这个原则在本仓库另一篇文档 find-records-that-contain-duplicate-values.md 中有同样体现——那里用having count(*) 1来抓取重复记录select email, count(*) from mailing_list group by email having count(*) 1 order by email;两者共享同一个语法骨架group by 分组键 having 聚合条件。示例数据与预期输出沿用本仓库文档中反复出现的authors/books数据模型执行上面的查询结果大致如下id | name | count ------------------- 1 | J.K.R | 7 3 | G.R.R | 5 8 | S.K. | 2只有书籍数 ≥ 2 的作者才会出现在结果集中写了 0 本或 1 本的作者比如尚未出版任何书籍的新作者不会出现——这正是join内连接与having过滤共同作用的结果内连接天然丢弃没有书的作者having再丢弃只有 1 本书的作者。阈值与变体 2、 N 与 BETWEENhaving count(...) 2中的2是阈值可自由调整以满足不同业务口径业务诉求having 写法至少 2 条关联记录having count(books.id) 2恰好 N 条关联记录having count(books.id) N35 条关联记录having count(books.id) between 3 and 5零关联记录的父表记录改用left join并having count(books.id) 0最后一种值得一提若想反向找出没有关联任何书籍的作者需要把join换成left join否则内连接会直接把这类作者过滤掉having count(books.id) 0便无从谈起。计数聚合的进阶count 之外的选择count只是聚合函数之一。当需求升级——比如想知道每位作者名下有多少本可借阅的书本仓库的 count-the-number-of-trues-in-an-aggregate-query.md 给出了用sum case实现的方案select author_id, sum(case when available then 1 else 0 end) from books group by author_id;同理如果你希望结果集中不仅展示数量还把每本书的书名一并带上可以用array_agg把关联记录的某列聚合进一个数组详见 aggregate-a-column-into-an-array.mdselect authors.id, count(books.id), array_agg(books.title) from authors join books on authors.id books.author_id group by authors.id having count(books.id) 2;对结果排序当作者数量很大时可以像 count-how-many-records-there-are-of-each-type.md 中那样用 select 列表的位置索引给聚合结果排序例如按书籍数量降序展示select authors.id, authors.name, count(books.id) from authors join books on authors.id books.author_id group by authors.id having count(books.id) 2 order by 3 desc;这里的3引用 select 中的第三个参数count(books.id)避免重复书写整段聚合表达式。性能与索引建议这条查询在数据量大时的执行路径依赖两个点join 条件与外键。建议确保books.author_id上有索引外键约束通常会自动创建否则 join 会演变成全表扫描确保group by使用的authors.id是主键PostgreSQL 可借助主键索引高效分组。若需要在大表上为author_id补建外键约束以保障数据完整性同时希望降低锁表影响可参考 add-foreign-key-constraint-without-a-full-lock.md 中先not valid后validate constraint的两步法将加锁成本控制在SHARE UPDATE EXCLUSIVE级别。小结查找拥有多条关联记录的父表记录是一个可复用的 SQL 模式其本质是用join建立关联用group by按父表主键聚合用count或其他聚合函数度量关联记录数用having对聚合值设定过滤阈值。掌握这一组合你便能同时解决查多本书的作者查重复邮箱按类型统计数量等一系列基于分组聚合的过滤问题相关兄弟主题可继续在仓库的 postgres 目录下对照阅读。赞分享文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载相关推荐RevokeMsgPatcher深度解析Windows平台微信/QQ/TIM防撤回完整方案RevokeMsgPatcher深度解析Windows平台微信/QQ/TIM防撤回完整方案 在日常使用微信、QQ、TIM等即时通讯软件时你是否经常遇到重要消桌面应用即时通讯掌握GORM分组查询从Group By到Having的完整实战指南掌握GORM分组查询从Group By到Having的完整实战指南 GORM作为Golang生态中最受欢迎的ORM库以其开发者友好的设计理念简化了数据库操作后端数据库ORMPostgreSQL 使用 GROUP BY 与 COUNT 统计每种类型Type的记录数PostgreSQL 使用 GROUP BY 与 COUNT 统计每种类型Type的记录数 导读 在 PostgreSQL 日常开发与数据分析中最常遇到的文档教程知识库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

从CC2530到ESP32-C6:Zigbee mesh组网实战与故障排查全攻略

从CC2530到ESP32-C6:Zigbee mesh组网实战与故障排查全攻略

上个月朋友喊我帮忙调一套温室大棚的无线采集方案,他手里堆了一堆 SPI 接口的 WiFi 模块,说要把几十个传感器节点组起来。我现场看了眼节点数量、电池供电方式和现场钢结构遮挡,直接劝他换成 Zigbee 组网方案。折腾了大半个月,从协…

2026/10/13 17:56:06 阅读更多 →
Spring AI 初体验:配好 yml 就能聊,ChatClient 四步链式调用

Spring AI 初体验:配好 yml 就能聊,ChatClient 四步链式调用

Spring AI 初体验:配好 yml 就能聊,ChatClient 四步链式调用作者:鱼宵 | Spring AI 实战精通营 第 1 篇上周有个同事在群里发了张截图:一个 Spring Boot 工程,代码里从头到尾没出现一个"模型"类…

2026/10/11 10:26:29 阅读更多 →
为什么你的企业上系统总是失败?一个毛巾厂“1个月vs1周“的真实案例

为什么你的企业上系统总是失败?一个毛巾厂“1个月vs1周“的真实案例

很多企业主找我聊数字化转型,开口第一句话是:"有没有好用的进销存系统推荐?"我的回答往往是:先别急着选系统,看看你手上的数据准备好了没有。今天讲一个我经手的真实案例,也许能帮正在准备上系统…

2026/10/12 14:49:50 阅读更多 →

最新新闻

Service层命名规范:从见名知意到代码可维护性

Service层命名规范:从见名知意到代码可维护性

接手一个业务系统,我最怕看到的不是复杂算法,而是那种一打开就让人头晕的 Service 实现类。2000 行起步,方法名字从 process 到 handle 再到 doSomething,翻遍整个类也猜不出某个方法是干嘛的。命名这种事,看起来不影响…

2026/10/13 17:55:28 阅读更多 →
Windows内核模块枚举与隐藏原理深度解析

Windows内核模块枚举与隐藏原理深度解析

1. 这不是“找模块”,而是在内核内存里做一次精准外科手术“枚举和隐藏内核模块”——这八个字在安全研究、驱动开发或系统调试场景中,绝不是一句轻飘飘的技术术语。它背后是一整套对Windows内核运行时状态的深度观测与主动干预能力。我第一次在某高校实…

2026/10/13 17:55:28 阅读更多 →
Hibernate二级缓存Provider详解:从原理到选型与排坑

Hibernate二级缓存Provider详解:从原理到选型与排坑

被人突然问起“Hibernate的caching provider是什么”,我第一反应是:能问出这个词的人,多半已经看到配置文件里那一堆以hibernate.cache开头的键,但又没搞懂这些键到底在切换什么。这篇文章就把这个词拆开讲清楚,重点解…

2026/10/13 17:55:28 阅读更多 →
电能质量复合扰动识别:混沌集成决策树实战解析

电能质量复合扰动识别:混沌集成决策树实战解析

简介:这是一份面向电能质量复合扰动识别研究的MATLAB完整源程序包,对应知网论文《基于混沌集成决策树的电能质量复合扰动识别》,可作为电气工程、信号处理及机器学习方向的毕业设计或课题研究参考,帮助复现算法并开展对比实验。程…

2026/10/13 17:55:28 阅读更多 →
CentOS局域网DNS搭建:BIND9多域名权威解析实战

CentOS局域网DNS搭建:BIND9多域名权威解析实战

1. 为什么在CentOS上自建局域网DNS不是“多此一举”,而是刚需落地的第一步很多人看到“CentOS搭建局域网DNS”第一反应是:不就是改个/etc/resolv.conf?内网查个主机名用/etc/hosts不就完事了?我试过——在某高校实验室的物联网教学…

2026/10/13 17:55:28 阅读更多 →
ActiveMQ consumerCount精准获取与实战调优指南

ActiveMQ consumerCount精准获取与实战调优指南

1. 项目概述:为什么“获取消费者数量”是 ActiveMQ 运维与调优的黄金指标在某公司消息中间件团队的实际运维中,我接手的第一个紧急故障就和consumerCount直接相关——一个订单履约服务突然延迟飙升,下游库存扣减平均耗时从200ms暴涨到8秒。排…

2026/10/13 17:54:25 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →