【postgresql 基础入门】多表联合查询 join与union 并,交,差等集合操作,两者的区别之处
多表数据联合查询
专栏内容:
- postgresql内核源码分析
- 手写数据库toadb
- 并发编程
开源贡献:
- toadb开源库
个人主页:我的主页
管理社区:开源数据库
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.
系列文章
- 入门准备
- postgrersql基础架构
- 快速使用
- 初始化集群
- 数据库服务管理
- psql客户端使用
- pgAdmin图形化客户端
- 数据库的使用
- 创建数据库
- 数据库操作
- 表的使用
- 表的创建
- 表的操作
- 数据查询
- 数据查询
- 多表联合查询
文章目录
- 多表数据联合查询
- 系列文章
- 前言
- 概述
- 原理介绍
- 多表 join 连接操作
- 1. 内连接(INNER JOIN)
- 2. 左连接(LEFT JOIN)
- 3. 右连接(RIGHT JOIN)
- 4. 全连接(FULL JOIN)
- 多表union 操作
- 联合类型说明
- 1. union
- 2. union all
- 3. except
- 3. intersect
- 总结
- 结尾
前言
postgresql 数据库是一款通用的关系型数据,在开源数据库中能与商业数据媲美,在业界也越来越流行。
因为是开源数据库,不仅公开源码,还有很多使用案例,好用的插件,所以它的慢慢变成了数据库的先驱和标准,通过postgresql可以很好从使用到原理,彻底搞懂;
如果是学习编程,也可以学到丰富的编程知识,数据结构,编程技巧,它里面还有很多精妙的架构设计,分层思想,可以灵活定制的思想。
本专栏主要介绍postgresql 入门使用,数据库维护管理,通过这些使用来了解数据库原理,慢慢了解postgresql是什么样的数据库,能做那些事情,以及如何做好服务,最关键的是这些知识都是面试的必备项。
概述
我们在实际应用中查询数据,往往涉及到多表的数据,如何使用一条SQL就能得到结果呢?
本文就来分享一下,多表数据的查询方法,并举例说明它们使用的技巧;
原理介绍
多表数据的联合查询,在postgresql 中有两个基本方法:
- join 连接操作;
- union 联合子查询;
多表join连接,其实就是通过某个列作为纽带,将多个实际的表连接成一张大表,然后在大表上进行查询;
而union 与 join 完全不同, union 通过联合 多个子查询结果,也就是说union 操作的是查询结果,将多个结果集合并成一个结果集,然后在这个总结果集上再进行二次查询处理;
也就是我们数学中的集合的几种
而更加总结的话,就涉及到关系代数中对于集合的操作:
集合操作主要包括以下几种:
- 并集操作(Union):将两个集合合并成一个集合,包括所有属于两个集合的元素。
- 交集操作(Intersection):将两个集合的公共元素组成一个新的集合。
- 差集操作(Difference):从一个集合中去掉属于另一个集合的元素,剩下的元素组成一个新的集合。
- 对称差集操作(Symmetric Difference):将属于一个集合但不属于另一个集合的元素,以及属于另一个集合但不属于一个集合的元素组成一个新的集合。
- 笛卡尔积操作(Cartesian Product):将两个集合的所有可能有序对组成一个新的集合。
多表 join 连接操作
在PostgreSQL中,多表查询是通过使用连接(JOIN)和交叉连接(CROSS JOIN)等操作来实现的。
连接操作是指将两个或多个表按照指定的条件进行关联,以获得它们之间的关系数据。
下面我们举例来说明,首先创建两张表custom 和 order;
以下是一个使用PostgreSQL进行JOIN操作的案例:
假设我们有两个表:customers和orders。customers表包含客户的信息,而orders表包含订单的信息。这两个表通过一个共同的字段customer_id相关联。
首先,让我们创建这两个表并插入一些数据:
CREATE TABLE customers (customer_id INT PRIMARY KEY,name VARCHAR(50),email VARCHAR(50)
);CREATE TABLE orders (order_id INT PRIMARY KEY,customer_id INT,order_date DATE,total_amount DECIMAL(10,2)
);INSERT INTO customers (customer_id, name, email)
VALUES (1, 'John Doe', 'john@example.com'),(2, 'Jane Smith', 'jane@example.com'),(3, 'Bob Johnson', 'bob@example.com'),(4, 'Steven John', 'steven@example.com'),(5, 'Kenidy', 'Kenidy@example.com');INSERT INTO orders (order_id, customer_id, order_date, total_amount)
VALUES (1, 1, '2023-01-01', 100.00),(2, 1, '2023-02-01', 200.00),(3, 2, '2023-02-15', 150.00),(4, 3, '2023-03-01', 75.00);
1. 内连接(INNER JOIN)
将两个表中的行进行匹配,返回满足连接条件的行。语法如下:
postgres=# SELECT * FROM customers INNER JOIN orders ON customers.customer_id = orders.customer_id;customer_id | name | email | order_id | customer_id | order_date | total_amount
-------------+-------------+------------------+----------+-------------+------------+--------------1 | John Doe | john@example.com | 1 | 1 | 2023-01-01 | 100.001 | John Doe | john@example.com | 2 | 1 | 2023-02-01 | 200.002 | Jane Smith | jane@example.com | 3 | 2 | 2023-02-15 | 150.003 | Bob Johnson | bob@example.com | 4 | 3 | 2023-03-01 | 75.00
(4 rows)
这里特意用 * 查出结果集中的所有列,让我们可以清晰看到结果集的全貌,可以看到join后的结果集,是两表的所有列的合并;
对于内联连,只是列出了符合连接条件的行,大家想一想,还有什么写法可以达到这种效果 。
对于, 条件写到where子句中也可以,所以内联接与where条件是等价的;
postgres=# select * from customers,orders where customers.customer_id = orders.customer_id;customer_id | name | email | order_id | customer_id | order_date | total_amount
-------------+-------------+------------------+----------+-------------+------------+--------------1 | John Doe | john@example.com | 1 | 1 | 2023-01-01 | 100.001 | John Doe | john@example.com | 2 | 1 | 2023-02-01 | 200.002 | Jane Smith | jane@example.com | 3 | 2 | 2023-02-15 | 150.003 | Bob Johnson | bob@example.com | 4 | 3 | 2023-03-01 | 75.00
(4 rows)
2. 左连接(LEFT JOIN)
在内连接的基础上,将左侧表中的所有行都包含在结果集中,即使右侧表中没有匹配的行。语法如下:
postgres=# select * from customers left join orders on customers.customer_id = orders.customer_id;customer_id | name | email | order_id | customer_id | order_date | total_amount
-------------+-------------+--------------------+----------+-------------+------------+--------------1 | John Doe | john@example.com | 1 | 1 | 2023-01-01 | 100.001 | John Doe | john@example.com | 2 | 1 | 2023-02-01 | 200.002 | Jane Smith | jane@example.com | 3 | 2 | 2023-02-15 | 150.003 | Bob Johnson | bob@example.com | 4 | 3 | 2023-03-01 | 75.005 | Kenidy | Kenidy@example.com | | | |4 | Steven John | steven@example.com | | | |
(6 rows)
左联接后的结果集,列也是两表的合并,而行数与之前不同,左边表列表出所有行,而右边的表只列出了符合条件的行,对于左表多出的行,右表以空代替;
3. 右连接(RIGHT JOIN)
在内连接的基础上,将右侧表中的所有行都包含在结果集中,即使左侧表中没有匹配的行。语法如下:
postgres=# select * from customers right join orders on customers.customer_id = orders.customer_id;customer_id | name | email | order_id | customer_id | order_date | total_amount
-------------+-------------+------------------+----------+-------------+------------+--------------1 | John Doe | john@example.com | 1 | 1 | 2023-01-01 | 100.001 | John Doe | john@example.com | 2 | 1 | 2023-02-01 | 200.002 | Jane Smith | jane@example.com | 3 | 2 | 2023-02-15 | 150.003 | Bob Johnson | bob@example.com | 4 | 3 | 2023-03-01 | 75.00
(4 rows)
右联接与左联接类似,结果集的行包括右表的所有行,左表只有符合联接表条件行;
4. 全连接(FULL JOIN)
相当于在左连接和右连接的基础上,同时做左连接和右连接,并返回两侧表中所有满足条件的行。语法如下:
postgres=# select * from customers full join orders on customers.customer_id = orders.customer_id;customer_id | name | email | order_id | customer_id | order_date | total_amount
-------------+-------------+--------------------+----------+-------------+------------+--------------1 | John Doe | john@example.com | 1 | 1 | 2023-01-01 | 100.001 | John Doe | john@example.com | 2 | 1 | 2023-02-01 | 200.002 | Jane Smith | jane@example.com | 3 | 2 | 2023-02-15 | 150.003 | Bob Johnson | bob@example.com | 4 | 3 | 2023-03-01 | 75.005 | Kenidy | Kenidy@example.com | | | |4 | Steven John | steven@example.com | | | |
(6 rows)
全联接就是包括左右两条的所有行,没有符合条件的行以空代替;
多表union 操作
PostgreSQL中的联合查询是一种将多个SELECT语句的结果组合成一个结果集的方法。它允许您从多个表或查询中获取数据,并根据指定的条件将它们组合在一起。
联合查询的基本语法如下:
SELECT column1, column2, ...
FROM table1
UNION/UNION ALL/EXCEPT/INTERSECT
SELECT column1, column2, ...
FROM table2
WHERE condition;
这里有几个关键部分:
SELECT语句:用于指定要检索的列和表。UNION、UNION ALL、EXCEPT和INTERSECT:这些关键字用于指定要执行的联合操作类型。WHERE子句:可选的条件,用于筛选结果。
联合类型说明
UNION:返回两个查询结果的并集,但会删除重复的行。UNION ALL:返回两个查询结果的并集,包括重复的行。EXCEPT:返回第一个查询结果中存在但在第二个查询结果中不存在的行。INTERSECT:返回两个查询结果中共有的行。
请注意,使用联合查询时,确保每个查询中选择的列数和列类型是一致的,否则可能会导致错误。
1. union
合并两个表的数据并删除重复行
postgres=# select customer_id from customers union select customer_id from orders ;customer_id
-------------23541
(5 rows)
这将返回一个结果集,其中包含两个表中所有不重复的行;
两个select 子句中的列数和类型必须一致才行,这样两个结果集才能合并到一起。
2. union all
合并两个表的数据并保留重复行
如果我们希望保留两个表中的所有行,包括重复的行,那么可以使用 UNION ALL 运算符。
postgres=# select customer_id from customers union all select customer_id from orders ;customer_id
-------------123451123
(9 rows)
这将返回一个结果集,其中包含两个表中所有的行,包括重复的行。
同时,如果想要对结果进行排序;
可以使用 ORDER BY 子句。例如:
postgres=# select customer_id from customers union all select customer_id from orders order by customer_id asc;customer_id
-------------111223345
(9 rows)
当然也可以加where 等其它子句;
3. except
获得两个集合的差,也就是前者集合中包括,而不属于后者集合的行;
postgres=# select customer_id from customers except select customer_id from orders ;customer_id
-------------54
(2 rows)
也就是查询还没有产生订单的客户ID列表;
3. intersect
INTERSECT运算符用于找出两个SELECT语句结果集的交集。它的语法如下:
postgres=# select customer_id from customers intersect select customer_id from orders order by customer_id asc;customer_id
-------------123
(3 rows)
这个类似于inner join,找到有订单的客户id列表;
总结
相同之处是,它们都是对结果集进行操作;
但是有明显的区别,join是将多表进行联接,产生结果集,然后再通过where等条件在联接后的结果集上再过滤;
而union并不限于表与表之间,而是对不同查询结果集,再进行集合操作,而且对于最终结果的列有要求,必须参与的集合列数量和类型要相同;
结尾
非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!
作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。
注:未经同意,不得转载!
相关文章:
【postgresql 基础入门】多表联合查询 join与union 并,交,差等集合操作,两者的区别之处
多表数据联合查询 专栏内容: postgresql内核源码分析手写数据库toadb并发编程 开源贡献: toadb开源库 个人主页:我的主页 管理社区:开源数据库 座右铭:天行健,君子以自强不息;地势坤&#x…...
很可惜,pyinstaller不是万能的
近期活不算少,但是真正新的东西很少,基本都是做些相似的功能,所以有精力想想之前悬而未决的问题,比如前两天写的加快软件启动速度的探索,这几天又想起一个之前没有解决的问题,这个问题之前也在博客写过&…...
0/1背包问题
例题HDU-2602 Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave … The bone collector had a big bag wi…...
Redis入门到精通——00数据类型
1、String 1.1、介绍 String 是最基本的 key-value 结构,key 是唯一标识,value 是具体的值,value其实不仅是字符串, 也可以是数字(整数或浮点数),value 最多可以容纳的数据长度是 512M 1.2、…...
PADS9.5使用记录
目录 一、概述 二、PADS Logic IN4148二极管封装 SOD-123封装 SOD-323封装 SOD-523封装 2N3904 1AM 三极管封装 78L05 7533-1 一、概述 PADS Logic 原理图绘制PADS Layout PCB 封装设计PADS Router 布线 二、PADS Logic …...
Axios post请求出现500错误
笔者在编写前端form表单传后端数据的时候,出现了以下问题 一、问题场景 当我用axios发送post请求的时候,出现了500错误 笔者找了很长时间错误,代码没问题,后端接口也没问题,后来发现问题出在实体类上了 当前端post请…...
【Leetcode】171.Excel 表列序号
一、题目 1、题目描述 给你一个字符串 columnTitle ,表示 Excel 表格中的列名称。返回 该列名称对应的列序号 。 例如: A -> 1 B -> 2 C -> 3 … Z -> 26 AA -> 27 AB -> 28 … 示例1: 输入: columnTitle = "A" 输出: 1示例2: 输入: colu…...
2023湖南省赛游记/题解
省赛拖了大哥们的后腿,感觉随便补个正常一队水平的人,我们一队肯定能AK。只能说自己真的菜,全程帮不上什么忙,还负贡献,真的想笑 B 暴力sg #include <bits/stdc.h> #define ll long long #define ull unsigned…...
海信电视U8KL使用体验:参数卷,画质技术也独有!
每个家庭成员对电视都有不同需求,如何能做到兼顾?看似需求众口难调,其实一台海信电视就能满足所有啦。 海信电视的参数不仅是最卷的,同时画质技术还是国内独有的,能把这样一台优秀的电视搬回家,无论电影、…...
E. Mishap in Club
题目: 样例1: 输入 --输出 1 样例2: 输入 --- 输出 3 思路: 数学贪心模拟思路,由于不知道在俱乐部的人数和在外面的人数,又要尽可能少的人数,那么定义两个变量,一个是里面的人数 i…...
UE4 自带体积云应用
新建空关卡 点击该选项 全部点击一遍 拖进场景...
RTP/RTCP 协议讲解
文章目录 前言一、RTP 协议1、RTP 协议概述2、RTP 工作机制3、RTP 协议的报文结构4、wireshark 抓取 RTP 报文 二、RTCP 协议1、RTCP 协议概述2、RTCP 工作机制3、RTCP 数据报4、wireshark 抓取 RTCP 报文 三、RTSP 和 RTP 的关系四、易混淆概念1、RTP over UDP 和 RTP over RT…...
倒计时15天!百度世界2023抢先看
近日消息,在10月17日即将举办的百度世界2023上,百度创始人、董事长兼首席执行官李彦宏将带来主题演讲,“手把手教你做AI原生应用”。 增设社会报名,有机会获得精美伴手礼 目前,百度世界大会已经开放公众参会报名&…...
Redis 哈希(Hash)数据类型和命令(数据类型 二)
基本概念 Hash是一个键值对的集合,其中每个键都是唯一的。每个键都可以关联多个字段和值,这使得Hash非常适合存储对象或结构化数据。 常用命令 存储、获取、删除:hset、hget、hdel # 添加键为name值为lin hset student name lin # 获取 h…...
[Linux]线程互斥
[Linux]线程互斥 文章目录 [Linux]线程互斥线程并发访问问题线程互斥控制--加锁pthread_mutex_init函数pthread_mutex_destroy函数pthread_mutex_lock函数pthread_mutex_unlock函数锁相关函数使用示例使用锁的细节加锁解锁的实现原理 线程安全概念常见的线程不安全的情况常见的…...
leetcode-239-滑动窗口最大值
题意描述: 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例: 输入:nums [1,3,-1,…...
基于大语言模型的智能问答系统应该包含哪些环节?
一个完整的基于 LLM 的端到端问答系统,应该包括用户输入检验、问题分流、模型响应、回答质量评估、Prompt 迭代、回归测试,随着规模增大,围绕 Prompt 的版本管理、自动化测试和安全防护也是重要的话题,本篇文章就来探索下这个过程…...
【Cesium创造属于你的地球】相机系统
相机系统里面有setView,flyTo,lookAt,viewBoundingsphere这几种方法,以下是相关的使用方法,学起来!!! setView 该方法可以直接切换相机视口,从而不需要通过一个飞入的效…...
运维困局下确保系统稳定的可行性
业务高速发展背后的困局 随着业务的快速发展,运维体系也逐步的完善起来。业务的稳定性和服务质量也在监控、可用性等体系的相互环抱下健康地成长。所有的问题、故障及影响稳定性的因素都在可控、可收敛的范围内,一切都向着好的方向发展。 这一切的背后…...
springmvc中DispatcherServlet关键对象
以下代码为 spring boot 2.7.15 中自带的 spring 5.3.29 RequestMappingInfo 请求方法相关信息封装,对应的信息解析在 RequestMappingHandlerMapping 的 createRequestMappingInfo() 中实现。 对于 RequestMapping 赋值的相关信息进行解析 protected RequestMappi…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
