联合查询(详细篇)

news2024/11/26 0:30:32

实际开发中往往数据来自不同的表 所以需要多表联合查询 多表查询是对多张表的数据取笛卡尔积

笛卡尔积

什么是笛卡尔积呢?

简单来说 笛卡尔积是两个表的乘积 结果集中的每一行都是第一个表的每一行与第二个表的每一行的组合

简单理解:

假设有两个表A和B 表A有m行 表B有n行 当对这两个表进行笛卡尔积操作时 生成的结果集将包含m*n个记录 这是因为结果集中的每一行都是表A中的一行与表B中的一行的组合

示例:

假设有两个表,一个是学生信息表(student),另一个是班级信息表(class)

学生信息表(student):

班级信息表(class):

对这两个表进行笛卡尔积操作,生成的结果集如下:

注意,这里的结果集中有两个名为“classid”的列,这是因为它们分别来自学生信息表和班级信息表。在实际应用中,为了避免混淆,通常会使用表名或别名来区分这些列

笛卡尔积的注意事项

1.性能问题:笛卡尔积操作会生成大量的数据,特别是当涉及的表很大时。这可能导致查询性能下降,甚至导致数据库崩溃。因此,在实际应用中应尽量避免无意的笛卡尔积操作。

2.无效数据:笛卡尔积操作生成的结果集中可能包含大量无效的数据。这些数据通常是由于没有指定连接条件而产生的。因此,在使用笛卡尔积时,应确保已经明确了所需的连接条件,并使用这些条件来过滤无效的数据。

3.使用JOIN代替:为了避免笛卡尔积操作带来的问题,通常建议使用JOIN操作来替代笛卡尔积。JOIN操作可以根据指定的连接条件来合并两个表的数据,从而生成更精确、更有用的结果集

联合查询

当需要从多个表中检索相似类型的数据 并将这些数据组合成一个结果集时 可以使用联合查询

内连接(inner join)

定义:内连接是最常用的联合查询方式 它只返回满足连接条件的行 可以通过多个表之间的共同字段来进行连接

特点:

1.只返回两个表中满足连接条件的行

2.如果两个表的某一对匹配的行在连接条件上不符合 那么这一对行就不会出现在结果集中

语法:

select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;

select 字段 from 表1 别名1,表2 别名2 where 连接条件 and 其他条件;

示例:

假设我们有两个表:employees(员工表)和departments(部门表)

内连接示例:

查询语句:

SELECT employees.name, departments.department_name  
FROM employees  
INNER JOIN departments  
ON employees.department_id = departments.id;

查询结果:

解释:

1.SELECT子句:指定了要从连接结果中选择的列,即employees.name和departments.department_name。

2.FROM子句:指定了第一个表employees。

3.INNER JOIN子句:表示执行内连接操作,连接employees表和departments表。

4.ON子句:指定了连接条件,即employees.department_id = departments.id。这意味着只有当employee表中的department_id与department表中的id相匹配时,才会返回相应的行

外连接

外连接是SQL中用于连接多个表的操作 它会返回符合连接条件的行 并且如果某个表中没有满足条件的匹配行 则使用NULL值填充 外连接主要包括左外连接、右外连接和全外连接(在某些数据库系统中,如MySQL中,可能不是直接支持的,但可以通过左外连接和右外连接的并集来实现)

我们这里先不讲解全外连接 

左外连接(left join)

左外连接:返回左表的所有行以及与其关联的右表的匹配行 如果右表中没有匹配行 则用NULL值填充

语法:

select * from 表1 left join 表2 on 连接条件;

示例:

假设我们有两个表:Customers(顾客表)和Orders(订单表)

左外连接示例:

MySQL查询语句:

SELECT Orders.OrderID, Customers.CustomerName, Orders.Product  
FROM Customers  
LEFT JOIN Orders  
ON Customers.CustomerID = Orders.CustomerID;

查询结果:

在这个结果中,Customers表中的所有行都返回了,即使它们在Orders表中没有匹配的订单。对于没有订单的顾客,OrderID和Product列显示为NULL

右外连接(right join)

右外连接:返回右表的所有行以及与其关联的左表中的匹配行 如果左表中没有匹配行 则用NULL值填充

语法:

select * from 表1 right join 表2 on连接条件;

MySQL查询语句:

SELECT Orders.OrderID, Customers.CustomerName, Orders.Product  
FROM Customers  
RIGHT JOIN Orders  
ON Customers.CustomerID = Orders.CustomerID;

查询结果:

与左外连接的结果相同,因为在这种情况下,两个表之间的连接条件是对称的。但通常,右外连接更常用于以右表为基础返回数据的场景

自连接

自连接是一种查询技术 它允许我们将同一张表视为两个不同的表(通常通过为表指定别名来实现) 然后基于这连个‘虚拟表’之间的某个共同字段(如ID)进行连接

语法:

SELECT 列名  
FROM 表名 AS 表别名1  
JOIN 表名 AS 表别名2  
ON 表别名1.列名 = 表别名2.列名  
WHERE 条件;

在这个语法中,使用AS关键字给表起了别名,以便区分两个表的使用。然后使用JOIN关键字指定连接条件,最后使用WHERE关键字指定额外的筛选条件

应用场景

自连接通常用于需要查询表中记录与自身记录相关联的场景 

例如,有一个员工表 其中包含员工的ID和上级领导的ID 我们想要查询每个员工的名字和他们的上级领导的名字 就可以使用自连接来实现

示例:

假设我们有一个名为employees的员工表,其结构如下:

CREATETABLE employees (  
    id INT PRIMARY KEY,  
    name VARCHAR(50),  
    supervisor_id INT  
);

并插入一些示例数据:

INSERT INTO employees (id, name, supervisor_id) VALUES  
(1, 'John', NULL),  
(2, 'Jane', 1),  
(3, 'Mike', 2),  
(4, 'Sarah', 1);

我们可以使用自连接来查询每个员工的名字和他们的上级领导的名字:

SELECT   
    e.name AS employee_name,  
    s.name AS supervisor_name  
FROM   
    employees AS e  
JOIN   
    employees AS s  
ON   
    e.supervisor_id = s.id;

执行上述查询后,我们将得到以下结果:

在这个结果中,我们成功地查询到了每个员工的名字以及他们的上级领导的名字。

另外,自连接还可以用于查询表中记录与其子类或父类记录相关联的场景,如层级分类等。此时,通常需要在表中添加一个字段来存储类别的子类或者父类的ID,然后通过自连接来查询层级关系

子查询

子查询是指 嵌入在 其他sql语句中的 select语句 也叫嵌套查询

单行子查询:返回一行记录的子查询

示例:

查询大于公司平均工资的员工姓名

SELECT name  
FROM employees  
WHERE salary > (SELECT AVG(salary) FROM employees);

多行子查询:返回多行记录的子查询

示例:查询语文英文课程的成绩信息

[NOT] IN 

-- 使用IN
select * from score where course_id 
in (select id from course where name='语文'or name='英文');

--使用 NOT IN
select * from score where course_id 
not in (select id from course where name!='语文'and name!='英文');

多列包含

 假设我们有两个表:employees(员工)和departments(部门)

返回每个部门中工资最高的员工的姓名和工资

SELECT e.name, e.salary, d.department_name  
FROM employees e  
JOIN departments d ON e.department_id = d.department_id  
WHERE (e.department_id, e.salary) 
IN (SELECT department_id, MAX(salary)  
  FROM employees  
  GROUP BY department_id  
);

结果:

[NOT] EXISTS

-- 使用 EXISTS
select * from score sco where 
exists (select sco.id from course cou 
where (name='语文'or name='英文') and cou.id = sco.course_id);

-- 使用 NOT EXISTS
select * from score sco where 
not exists (select sco.id from course cou where 
(name!='语文'and name!='英文') and cou.id = sco.course_id);

重点

在from子句中使用子查询:子查询语句出现在from子句中。这里要用到数据查询的技巧,把一个子查询当作一个临时表使用

示例2:

返回 工资高于其所在部门平均工资的 员工的姓名、工资和部门平均工资

SELECT e1.name, e1.salary, e2.avg_salary  
FROM employees e1  
JOIN 
(SELECT department_id, AVG(salary) AS avg_salary 
FROM employees GROUP BY department_id) e2  
ON e1.department_id = e2.department_id  
WHERE e1.salary > e2.avg_salary;

解释:

(SELECT department_id, AVG(salary) AS avg_salary 
FROM employees GROUP BY department_id)

首先被执行,它计算每个部门的平均工资,并生成一个包含department_idavg_salary的结果集。这个结果集在查询的上下文中被当作一个临时表,并被赋予别名e2

然后,外部查询使用这个临时表(e2)与employees表(别名为e1)进行连接,基于department_id字段匹配记录。最后,通过where子句过滤出工资高于部门平均工资的员工记录

合并查询

合并查询是指将两个或多个SELECT语句的结果集合并成一个大的结果集。这个特性使得合并查询成为了SQL语言中非常强大和常用的功能之一

在SQL中,合并查询主要使用两个操作符:UNION和UNION ALL

  1. UNION:将两个或多个查询的结果集合并在一起,并去除重复的行。UNION操作会对结果集进行排序和去重,因此可能需要大量的CPU和内存资源。

  2. UNION ALL:将两个或多个查询的结果集合并在一起,但不去除重复的行。与UNION相比,UNION ALL的性能通常更好,因为它不会进行排序和去重操作

~union

示例:

SELECT name, salary FROM employees_2022  
UNION  
SELECT name, salary FROM employees_2023;

 返回employees_2022employees_2023两个表中所有员工的姓名和工资信息,会去除重复的行

~union all

SELECT name, salary FROM employees_2022  
UNION ALL  
SELECT name, salary FROM employees_2023;

返回employees_2022employees_2023两个表中所有员工的姓名和工资信息,并且不会去除重复的行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2210637.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

复位电路的亚稳态

复位导致亚稳态的概念: 同步电路中,输入数据需要与时钟满足setup time和hold time才能进行数据的正常传输(数据在这个时间段内必须保持不变:1不能变为0,0也不能变为1),防止亚稳态; …

FPGA实现PCIE采集电脑端视频缩放后转千兆UDP网络输出,基于XDMA+PHY芯片架构,提供3套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的PCIE方案我这里已有的以太网方案本博已有的FPGA图像缩放方案 3、PCIE基础知识扫描4、工程详细设计方案工程设计原理框图电脑端视频PCIE视频采集QT上位机XDMA配置及使用XDMA中断模块FDMA图像缓存纯Verilog图像缩放模块详解…

前端接口报500如何解决 | 发生的原因以及处理步骤

接口500,通常指的是服务器内部错误(Internal Server Error),是HTTP协议中的一个标准状态码。当服务器遇到无法处理的错误时,会返回这个状态码。这种错误可能涉及到服务器配置、服务器上的应用程序、服务器资源、数据库…

【畅捷通-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…

图说谭教授的“Δy=dy”是误人子弟的概念性错误。

黄小宁 可建立如图所示的局部坐标系。图中曲线Δydy余项不是关于dx的一次函数,而切线dyydx是关于dx的一次函数。草图形象直观地显示曲线Δy不切线dy。 所以谭教授书中的“Δydy余项dy”是误人子弟的概念性错误。数学家王元说:搞错概念脑子会变成一团浆糊…

离岗睡岗预警系统 值班室离岗识别系统Python 结合 OpenCV 库

在众多工作场景中,存在着一些特殊岗位,这些岗位对于人员的专注度和警觉性有着极高的要求。然而,离岗睡岗现象却时有发生,给工作的正常开展和安全保障带来了严重的威胁。本文将深入探讨特殊岗位离岗睡岗的危害,以及如何…

解决方案:AttributeError: Can only use .str accessor with string values!

文章目录 一、现象二、解决方案 一、现象 最近在用Pandas库处理日期数据的时候,有时候想截取后两个数字,却截取不了,时间久了,会有些遗忘,去找大模型提问找答案,于是做个笔记记录,帮助后面遇见…

docker,docker-desktop,docker-compose download

docker docker-compose download 百度网盘获取离线包链接release-notes 参考dockerdocker-composewlspowershell

程序猿成长之路之设计模式篇——创建型设计模式——抽象工厂模式

设计模式开篇之作,简单介绍一下抽象工厂设计模式 前言 试想一下,国内有两个工厂,工厂1和工厂2,这两个不同牌子的工厂生产同样类型的商品,但是商品的价格和数量不一致,这时候我们要对其进行设计&#xff0c…

Centos基线自动化检查脚本

此脚本是一个用于检查Linux系统安全配置的Bash脚本。它通过多项安全标准对系统进行评估,主要检查以下内容: IP地址获取:脚本首先获取主机的IP地址,确保其以10.115开头。 密码策略检查: 检查最小密码长度(P…

解析 wxPython 和 Pandas 实现的 XLSX 分析器和网页打开器

在本文中,我们将分析一个使用 wxPython 和 Pandas 库编写的 Python 应用程序,名为 “XLSX Analyzer and Web Opener”。该应用程序的核心功能是:从 Excel 文件中读取数据并显示在网格中,此外,还允许用户使用 Google Ch…

力扣面试150 汇总区间 双指针 StringBuilder

Problem: 228. 汇总区间 &#x1f468;‍&#x1f3eb; 参考题解 import java.util.ArrayList; import java.util.List;class Solution {public List<String> summaryRanges(int[] nums) {List<String> ret new ArrayList<String>(); // 存储结果的列表in…

Faster R-CNN模型微调检测航拍图像中的小物体

关于深度实战社区 我们是一个深度学习领域的独立工作室。团队成员有&#xff1a;中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等&#xff0c;曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝&#xff0c;拥有2篇国家级人工智能发明专利。 社区特色…

【排序算法】选择排序的全面剖析(含详细图解)

在之前文章中我们了解到了插入排序&#x1f449;【插入排序】&#xff0c;现在我们来学习排序算法中的直接选择排序。 目录 &#x1f4af;引言 &#x1f4af;选择排序的原理 &#x1f4af;选择排序的实现步骤 ⭐简单选择排序&#xff08;以升序为例&#xff09; ⭐代码实…

Human-M3 多模态姿态估计数据集-初步解读

文章概述(个人总结):该论文重点提出一个用于人体姿态估计的RGB+点云数据集,针对该多模态数据集,作者阐述了数据集的收集、数据标注以及该数据集的特点。并提出了一个简单的多模态3D人体姿态估计算法,对比其他模型,该方法性能较好。最后总结了该数据集和该方法的限制。 …

沪尚茗居装修秘籍:嵌入式蒸烤箱,让厨房生活更精彩

在装修厨房时&#xff0c;选择一款合适的嵌入式蒸烤箱不仅能提升烹饪效率&#xff0c;还能为厨房增添一份现代感。沪尚茗居深知用户对厨房电器的需求&#xff0c;从实际出发&#xff0c;为用户推荐选购嵌入式蒸烤箱的实用技巧&#xff0c;让厨房生活更加美好。    首先&…

【千库网-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

leetcode二叉树(二)-二叉树的递归遍历

题目 . - 力扣&#xff08;LeetCode&#xff09; . - 力扣&#xff08;LeetCode&#xff09; . - 力扣&#xff08;LeetCode&#xff09; 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出…

滑块验证码,给图就行

效果如上~ <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>滑块拼图验证码 - 拖动条 Loading 效…

K8s环境下使用sidecar模式对EMQX的exhook.proto 进行流量代理

背景 在使用emqx作为mqtt时需要我们需要拦截client的各种行为&#xff0c;如连接&#xff0c;发送消息&#xff0c;认证等。除了使用emqx自带的插件机制。我们也可以用多语言-钩子扩展来实现这个功能&#xff0c;但是目前emqx仅仅支持单个grpc服务端的设置&#xff0c;所以会有…