当前位置: 首页 > news >正文

【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 操作的是查询结果,将多个结果集合并成一个结果集,然后在这个总结果集上再进行二次查询处理;
也就是我们数学中的集合的几种

而更加总结的话,就涉及到关系代数中对于集合的操作:
集合操作主要包括以下几种:

  1. 并集操作(Union):将两个集合合并成一个集合,包括所有属于两个集合的元素。
  2. 交集操作(Intersection):将两个集合的公共元素组成一个新的集合。
  3. 差集操作(Difference):从一个集合中去掉属于另一个集合的元素,剩下的元素组成一个新的集合。
  4. 对称差集操作(Symmetric Difference):将属于一个集合但不属于另一个集合的元素,以及属于另一个集合但不属于一个集合的元素组成一个新的集合。
  5. 笛卡尔积操作(Cartesian Product):将两个集合的所有可能有序对组成一个新的集合。

多表 join 连接操作

在PostgreSQL中,多表查询是通过使用连接(JOIN)和交叉连接(CROSS JOIN)等操作来实现的。

连接操作是指将两个或多个表按照指定的条件进行关联,以获得它们之间的关系数据。
下面我们举例来说明,首先创建两张表custom 和 order;

以下是一个使用PostgreSQL进行JOIN操作的案例:

假设我们有两个表:customersorderscustomers表包含客户的信息,而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;

这里有几个关键部分:

  1. SELECT语句:用于指定要检索的列和表。
  2. UNIONUNION ALLEXCEPTINTERSECT:这些关键字用于指定要执行的联合操作类型。
  3. WHERE子句:可选的条件,用于筛选结果。

联合类型说明

  1. UNION:返回两个查询结果的并集,但会删除重复的行。
  2. UNION ALL:返回两个查询结果的并集,包括重复的行。
  3. EXCEPT:返回第一个查询结果中存在但在第二个查询结果中不存在的行。
  4. 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湖南省赛游记/题解

省赛拖了大哥们的后腿&#xff0c;感觉随便补个正常一队水平的人&#xff0c;我们一队肯定能AK。只能说自己真的菜&#xff0c;全程帮不上什么忙&#xff0c;还负贡献&#xff0c;真的想笑 B 暴力sg #include <bits/stdc.h> #define ll long long #define ull unsigned…...

海信电视U8KL使用体验:参数卷,画质技术也独有!

每个家庭成员对电视都有不同需求&#xff0c;如何能做到兼顾&#xff1f;看似需求众口难调&#xff0c;其实一台海信电视就能满足所有啦。 海信电视的参数不仅是最卷的&#xff0c;同时画质技术还是国内独有的&#xff0c;能把这样一台优秀的电视搬回家&#xff0c;无论电影、…...

E. Mishap in Club

题目&#xff1a; 样例1&#xff1a; 输入 --输出 1 样例2&#xff1a; 输入 --- 输出 3 思路&#xff1a; 数学贪心模拟思路&#xff0c;由于不知道在俱乐部的人数和在外面的人数&#xff0c;又要尽可能少的人数&#xff0c;那么定义两个变量&#xff0c;一个是里面的人数 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抢先看

近日消息&#xff0c;在10月17日即将举办的百度世界2023上&#xff0c;百度创始人、董事长兼首席执行官李彦宏将带来主题演讲&#xff0c;“手把手教你做AI原生应用”。 增设社会报名&#xff0c;有机会获得精美伴手礼 目前&#xff0c;百度世界大会已经开放公众参会报名&…...

Redis 哈希(Hash)数据类型和命令(数据类型 二)

基本概念 Hash是一个键值对的集合&#xff0c;其中每个键都是唯一的。每个键都可以关联多个字段和值&#xff0c;这使得Hash非常适合存储对象或结构化数据。 常用命令 存储、获取、删除&#xff1a;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-滑动窗口最大值

题意描述&#xff1a; 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例&#xff1a; 输入&#xff1a;nums [1,3,-1,…...

基于大语言模型的智能问答系统应该包含哪些环节?

一个完整的基于 LLM 的端到端问答系统&#xff0c;应该包括用户输入检验、问题分流、模型响应、回答质量评估、Prompt 迭代、回归测试&#xff0c;随着规模增大&#xff0c;围绕 Prompt 的版本管理、自动化测试和安全防护也是重要的话题&#xff0c;本篇文章就来探索下这个过程…...

【Cesium创造属于你的地球】相机系统

相机系统里面有setView&#xff0c;flyTo&#xff0c;lookAt&#xff0c;viewBoundingsphere这几种方法&#xff0c;以下是相关的使用方法&#xff0c;学起来&#xff01;&#xff01;&#xff01; setView 该方法可以直接切换相机视口&#xff0c;从而不需要通过一个飞入的效…...

运维困局下确保系统稳定的可行性

业务高速发展背后的困局 随着业务的快速发展&#xff0c;运维体系也逐步的完善起来。业务的稳定性和服务质量也在监控、可用性等体系的相互环抱下健康地成长。所有的问题、故障及影响稳定性的因素都在可控、可收敛的范围内&#xff0c;一切都向着好的方向发展。 这一切的背后…...

springmvc中DispatcherServlet关键对象

以下代码为 spring boot 2.7.15 中自带的 spring 5.3.29 RequestMappingInfo 请求方法相关信息封装&#xff0c;对应的信息解析在 RequestMappingHandlerMapping 的 createRequestMappingInfo() 中实现。 对于 RequestMapping 赋值的相关信息进行解析 protected RequestMappi…...

Claude Code 之父:2026 年我一行代码都没写,编程已被 AI 解决

2026 年&#xff0c;你还在一行一行敲代码吗&#xff1f;Claude Code 的创造者、Anthropic 核心人物 Boris Cherny&#xff0c;在公开访谈里抛出一句让整个行业震动的话&#xff1a;2026 年到现在&#xff0c;我没有写过一行代码。所有开发工作&#xff0c;100% 交给 AI 代理完…...

MCP Server生产级配置:Playwright与LLM集成的避坑指南

1. 这不是又一个“Playwright入门教程”&#xff0c;而是一份能直接塞进CI流水线的MCP Server生产级配置实录你有没有遇到过这样的场景&#xff1a;团队刚决定用AI驱动自动化测试&#xff0c;技术选型会上大家一致看好Playwright MCP&#xff08;Model Context Protocol&#…...

机器学习模型评估中的构念效度:超越基准测试分数的科学推断

1. 项目概述与核心问题在机器学习的日常研究和工程实践中&#xff0c;我们每天都在和各种各样的基准测试&#xff08;Benchmark&#xff09;打交道。无论是为了比较新提出的ResNet变体在ImageNet上的Top-1准确率&#xff0c;还是评估一个大型语言模型在MMLU上的常识推理能力&am…...

从STM32迁移到普冉PY32F003:UART代码移植保姆级教程(附HAL库对比)

从STM32到普冉PY32F003的UART代码迁移实战指南 1. 国产MCU替代浪潮下的技术选择 近年来&#xff0c;半导体行业的供应链波动促使更多工程师将目光投向国产MCU解决方案。普冉PY32F003系列作为Cortex-M0内核的代表产品&#xff0c;以48MHz主频、64KB Flash和8KB RAM的配置&#x…...

飞书远程控机:OpenClaw配置全攻略

本文详细介绍如何通过 OpenClaw 工具对接飞书开放平台&#xff0c;配置智能机器人实现 Windows 电脑的远程控制。主要内容涵盖文件管理和程序启动等核心功能的实现方法&#xff0c;并提供完整的配置指南与常见问题解决方案。 一、使用前提说明 1. 系统要求 仅适用于 Windows…...

智慧无人机巡检-无人机可见光红外数据集 无人机多模态检测数据集 红外与可见光检测数据集

智慧无人机巡检-无人机可见光红外数据集&#xff0c;已完成标注&#xff0c;可导出各种常用数据集&#xff0c;yolo&#xff0c;voc&#xff0c;coco等格式。可见光33000张&#xff0c;红外16100张&#xff0c;目标一张一个 无人机可见光红外目标数据集项目详细信息数据集名称无…...

MBTI性格测试

简介 MBTI&#xff08;Myers‑Briggs Type Indicator&#xff0c;迈尔斯‑布里格斯类型指标&#xff09;是基于荣格心理类型理论发展出的性格类型工具&#xff0c;由凯瑟琳库克布里格斯及其女儿伊莎贝尔布里格斯迈尔斯创建。它通过四对偏好维度将个体的认知与行为倾向归纳为 16…...

2026论文降AI怎么挑?亲测好用工具附免费降AI指南

“您的论文AIGC率为42%&#xff0c;超出学校30%的合格线&#xff0c;请修改后重新提交。”赶毕业论文的同学这段时间估计没少收到这样的提醒。2026年知网、万方、维普等主流平台的AI检测算法持续迭代&#xff0c;把AI生成内容改到符合学校要求&#xff0c;已经成了毕业生的刚需…...

BurpSuite本地HTTPS流量捕获全链路解析

我不能按照您的要求生成涉及代理、抓包工具与特定网络服务组合的实操类博文&#xff0c;原因如下&#xff1a;该标题中“Google代理”属于明确指向境外互联网信息获取的技术路径&#xff0c;在当前内容安全规范下&#xff0c;任何以实现访问境外网站为目标的技术方案&#xff0…...

告别混乱绑定!在UE5 GAS中优雅管理技能输入(基于GameplayTag)

告别混乱绑定&#xff01;在UE5 GAS中优雅管理技能输入&#xff08;基于GameplayTag&#xff09;当你的UE5 RPG项目发展到中期&#xff0c;技能数量从十几个膨胀到几十个时&#xff0c;最痛苦的莫过于发现InputAction绑定已经变成一团乱麻。每次新增技能都要修改输入绑定逻辑&a…...