MySQL多表查询(联合查询、连接查询、子查询)

news2024/9/24 1:23:41

目录

多表联合查询

联合查询类型

多表连接查询

多表查询的分类

交叉查询(笛卡尔积)

内连接查询

外连接查询

自连接查询

子查询规则

子查询的分类

子查询的不同结果

EXISTS和NOT EXISTS

子查询应用的不同位置

不同外部语句的子查询应用情况


多表联合查询

1、通过联合查询,可以得到两张表中记录的集合或者公共记录的集合,或者其中某张表中的记录的集合

2、联合查询以行为单位对表进行操作,主要是进行行数的增减

3、作为联合查询的多表之间的列数、以及列数的类型必须相同(例如:表1查询哪些列,表2就查询哪些列)

4、联合查询默认会去除重复的记录

5、联合查询可以使用任何SELECT语句,但是ORDER BY子句只能在最后一次使用

联合查询类型

UNION             将两张表的某些字段的记录相加(并集)

ALL                  作为关键字,表示集合运算的结果保留重复行(一般为UNION ALL)

INTERSECT    将两张表的某些字段的公共记录提取出来(交集)(MySQL不存在,可以使用下述的连接查询代替)

EXCEPT         将两张表的某些字段的公共记录减去,然后返回一张表的剩余记录(差集)(MySQL不存在,使用NOT IN字段实现)

联合查询格式

Union格式

SELECT 字段列表 FROM 表A ……  UNION SELECT 字段列表 FROM 表B ……;

返回表A查询和表B查询的并集(并进行去重处理)

Union all格式

相比于Union查询,此查询可以对合并的数据不进行去重

联合查询演示

我们使用以下两表进行演示

select name,age from staff1 where origo='重庆' union select name,age from user;  #查询表1 origo为重庆的nameage字段的结果 加上表2查询nameage的结果,并进行去重处理(要求两表的nameage数据类型一致)

select name,age from staff1 where origo='重庆' union all select name,age from user; #没有进行去重处理

select name,age from staff1 where (name,age) not in (select name,age from user)#查询表1 与 表2 的差集(将表1的查询结果减去表1与表2的交集)


多表连接查询

多表查询是以横向列为单位,主要是将其他表的某些列添加过来

在进行多表查询时,SELECT子句中的列一般按照 表名的别名.列名 的格式书写

我们使用两张表来做演示讲解

多表查询的分类

交叉查询

       将两张表的全部记录交叉组合,所得的记录数是两张表行数的乘积

内连接查询

查询A、B两表交集部分的数据

外连接查询

       左外连接:查询左表所有数据,以及两张表交集部分的数据

       右外连接:查询右表所有数据,以及两张表交集部分的数据

自连接查询

只有一张表,当前表与自身进行连接查询(子连接必须使用表的别名)

交叉查询(笛卡尔积)

交叉连接通过使用集合运算符GROSS JOIN(笛卡尔积)来完成

将两张表的全部记录交叉组合,在添加了其他表字段的同时,所得的记录数是两张表行数的乘积

格式

SELECT 字段列表 FROM 表1,表2;  显示出来的数据量为表1的数据量*表2的数据量

注意事项

我们通过现象可以看到,其结果太多并且存在错误,没有太多实用价值,并且需要花费大量的运算时间;因此此查询在实际业务中并不会使用

不过此查询是所有表查询的基础

select user.name,career.name from user , career ;  #没有使用别名
select u.name,c.name from user u , career c#使用别名的方式进行交叉查询

内连接查询

可以选取出同时存在于两张表中的数据,即两张表的交集数据

分为隐式内连接和显示内连接,两者只是书写方式不同,得到的结果是完全相同的

隐式内连接

SELECT 字段列表 FROM 表1,表2 WHERE 条件列表;

显式内连接

SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件列表 [WHERE 判断语句] ;

INNER可以省略

如果要在此语句后续加入Where,则需要注意ON语句必须是在FROM和WHERE之间

执行顺序为:先进行显示内连接,再对连接的结果进行Where

注意事项

使用内连接可能会有漏掉的数据,会漏掉NULL值

select u.name,u.age,c.name from user u , career c  where u.career_id = c.id#隐式查询;选出user.career_idcareer.id相同的记录,并显示这些记录对应的user.nameuser,agecareer.name字段;此时如果user.career_id有空值或者career.id有空值,就会漏掉空值所对应的数据(此时就漏掉了老六的数据)
select u.name,u.age,c.name from user u join career c  on u.career_id = c.id#显式查询; 两次查询的结果都是下图

select u.name,u.age,c.name from user u join career c  on u.career_id = c.id where u.age > 20#显式查询 对以上结果进行筛选,选择年龄大于20的数据据

外连接查询

选取出单张表(主表)的全部信息,然后再加上两张表交集的信息

左外连接

SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件列表;

[OUTER] 可以省略

查询表1的所有数据,其中包含表1和表2交集部分的数据

select u.name,u.age,c.name from user u left join career c on u.career_id = c.id; #左外连接  显示user表对应nameage字段的全部信息,然后再加上user.career_idcareer.id的交集部分

右外连接

SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件列表;

[OUTER] 可以省略

查询表2的所有数据包含表1和表2交集部分的数据

select u.name,u.age,c.name from user u right join career c on u.career_id = c.id; #右外连接 显示career表对应name段的全部信息,然后再加上user.career_idcareer.id的交集部分

自连接查询

使用此表来做自连接查询的演示(此表记录的是员工与其对应的上司id表—即managerid对应的id的name就是上司名称)

自己连接自己进行查询,可以是内连接方式,也可以是外连接方式

格式

SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件列表;

select e1.name,e2.name '上司from emp e1 join emp e2 on e1.managerid = e2.id# 显示查询,查询每个员工对应的上司是谁;可以理解为将emp复制为表e1和表e2两张表,将e1表的managerid作为外键与e2id关联起来,然后显示e1表的namee2表的name(此处是使用显式内连接方式  会有遗漏)  
select e1.name,e2.name '上司' from emp e1 left join  emp e2 on e1.managerid = e2.id; #左外连接,员工没有领导也显示出来


子查询规则

子查询(Sub Query)也可以称为嵌套查询,是一种嵌套在其它SQL查询的Where子句中的查询;包含子查询的语句称为外部语句

  1. 子查询必须包含在()内
  2. 一般子查询的SELECT语句只有一个字段,除非外部语句中有多个列需要与子查询的列进行比较
  3. 子查询不可以直接应用在聚合函数中,子查询也无法使用ORDER BY
  4. Ntext、text、image数据类型不可以在子查询的选择列表中使用
  5. 关键字DISTINCT不能与包含GROUP BY的子查询一起使用

子查询的分类

根据子查询的结果不同,可以分为4类

标量子查询    子查询结果为单个值

列子查询       子查询结果为一列多行

行子查询       子查询结果为一行多列

表子查询       子查询结果为多行多列

根据子查询的不同位置,大致可以分为3类

子查询应用的位置主要有三种情况:

分别是WHERE之后、FROM之后、SELECCT之后

根据子查询的不同外部语句可以分为大致4类

子查询外部的语句可以是

INSERT / UPDATE / DELETE / SELECT的任何一个

子查询的不同结果

通过以下两表来进行查询

标量子查询——查询结果必须只能返回一行一列的结果,也就是某个值

由于其子查询的结果是单个值,所以可以用来进行算术运算

常用操作符: = 、 <> 、 > 、>= 、< 、 <=

select * from emp where dept_id=(select id from dept where name='销售部'); #查询销部对应的所有员工(先查询销售部对应的id,然后根据id查询员工)

select * from emp where entrydate >= (select entrydate from emp where name='张三'); #查询张三入职之后的所有员工信息(先查询张三的入职信息,再查询此时间之后的员工信息

列子查询——返回结果是一列多行

常用操作符:

IN           指定的集合范围内多选一

NOT IN 不在指定的集合范围之内

ANY       子查询返回列表中,有任意一个满足即可

SOME     等同于ANY

ALL         子查询返回列表的所有值都必须满足

select * from emp where salary > all(select salary from emp where dept_id=(select id from dept where name='研发部')); #查询比所有财务员工工资都高的员工信息(先查询财务部对应的id,通过此id查询财务部员工薪资,然后再找出大于此薪资的员工信息)

行子查询——返回结果是一行多列

常用操作符:=、<>、IN、NOT IN

select * from emp where (salary,managerid) = (select salary,managerid from emp where name='李四'); #查询与李四相同薪资与领导的其它员工信息

表子查询——返回结果是多行多列

常用的操作符:IN

经常出现在from之后

select * from emp where (dept_id,salary) in (select dept_id,salary from emp where name='老五' or name='李四'); #查询与老五或李四 的部门相同、工资相同的其它员工信息

select e.*,dept.name from (select * from emp where entrydate > '2001-01-01') e left join dept on e.dept_id = dept.id ; #查询入职时间大于2001-01-01之后的员工信息及其对应的部门信息

EXISTS和NOT EXISTS

格式为:EXISTS(子查询)

EXISTS用于检查子查询是否至少会返回一行数据;如果该子查询至少返回了一行数据,则为True;如果子查询没有返回数据,则为False

某些情况下,也可以使用IN或者ANY字段来代替

NOT EXISTS与EXIST相反

select * from emp where exists(select * from emp where id = 10); #只要有id=10的值,就查询emp表  结果为没有数据
select * from emp where exists(select * from emp where id = 1); #只要有id=1的值,就查询emp表    结果为emp表数据

子查询应用的不同位置

子查询应用的位置主要有三种情况,分别是WHERE之后、FROM之后、SELECCT之后

Where子句中——一般子查询都应用在where之后

我们上述所演示的都是where之后的子查询

大概格式:SELECT * FROM t1 WHERE column1= (SELECT column1 FROM t2);

From子句中——此时子查询返回的结果集将作为临时表,该表又称为派生表

派生表必须要配置别名,并且派生表的列名必须是唯一的

select * from 
    (select origo,count(*) as number from staff1 group by origo) as emp 
    where emp.number > 2; #根据居住地分组,并查询居住地人数大于2的(派生表的别名为emp)

Select之后——仅支持标量子查询,子查询返回的是单个值

SELECT (子查询) FROM 表1;

子查询返回的单个值是表1中的某个字段;此查询一般很少用到

不同外部语句的子查询应用情况

子查询外部的语句可以是INSERT / UPDATE / DELETE / SELECT的任何一个

根据以下两个表做的实验

SELECT语句中的子查询

select * from user where career_id =(select id from career where name='厨师'); #查询user中有哪些人是厨师(子查询查询厨师id,然后外部语句再查询此id对应的人员)

INSERT语句中的子查询

insert into user1 (name,age,career_id) 
    select * from user 
    where career_id in (select id from career); #user1表添加数据,添加的数据为user表中有职位的人

UPDATE语句中的子查询

update user set age = age * 1.5 where career_id = (select id from career where name ='厨师'); #将厨师的年龄乘1.5

DELETE语句中的子查询

delete from user where career_id =(select id from career where name='厨师'); #阐述user表中职业是厨师的信息

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

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

相关文章

spring boot--自动化注入组件原理、内嵌tomcat-1

前言 我们知道开发spring boot项目&#xff0c;在启动类上添加注解SpringBootApplication &#xff0c;然后引入要自动注入的组件依赖&#xff0c;然后现application.properties中加上相应配置就可以自动注入这个组件&#xff0c;那么下面看看自动注入组件是如何实现的 一、S…

Idea 结合docker-compose 发布项目

Idea 结合docker-compose 发布项目 这里写目录标题 Idea 结合docker-compose 发布项目Docker 开启远程访问功能 添加相应端口配置IDEA 链接Docker配置项目 docker-compose.yml本地还需要安装 dockerwin11 安装本地Docker 可能存在问题 Linux内核不是最新 Docker 开启远程访问功…

回文链表——力扣234

文章目录 题目描述法一 将值复制到数组中后用双指针法法二 快慢指针 题目描述 法一 将值复制到数组中后用双指针法 class Solution { public:bool isPalindrome(ListNode* head) {vector<int> v;while(head!NULL){v.emplace_back(head->val);head head->next;}for…

同步、异步、阻塞、非阻塞

一、概念 同步与异步&#xff08;线程间调用&#xff09;的区别&#xff1a;关注的是调用方与被调用方之间的交互方式。同步调用会等待被调用方的结果返回&#xff0c;而异步调用则不会等待结果立即返回&#xff0c;可以通过回调或其他方式获取结果。 阻塞非阻塞&#xff08;…

Nautilus Chain 即将治理通证 NAUT ,生态发展进程加速

独特且优势明显的Nautilus Chain 目前&#xff0c;行业内首个模块化底层Nautilus Chain已经上线主网&#xff0c;并且即将有超过70个应用原生部署在Nautilus Chain上。Nautilus Chain本身是一个以Layer3为定位的区块链系统&#xff0c;其通过Celestia模块化底层来获得DA支持以…

网络安全 HVV蓝队实战之溯源

一、前言 对于攻防演练蓝军的伙伴们来说&#xff0c;最难的技术难题可能就是溯源&#xff0c;尤其在今天代理横行的时代更加难以去溯源攻击者。这里我就举两个溯源来帮助大家梳理溯源过程&#xff0c;一个是只溯源到公司&#xff0c;一个是溯源到个人。 二、溯源实例 2.1IP …

逻辑运算符和短路求值

要了解短路求值就必须先了解什么是逻辑运算符。 逻辑运算符 在了解运算符之前我们必须先知道再JAVA中逻辑运算符的结果是Boolean类型的值 逻辑与“&&” 表达式1 && 表达式2 逻辑与就是只有运算符两边的表达式都为真&#xff0c;结果才为真。 表达式1表达式…

2023潮玩盲盒小程序盲盒商城源码(开源+微信登录+支付对接)

潮玩盲盒星尘潮玩盲盒小程序2023潮玩盲盒小程序盲盒商城源码(开源微信登录支付对接)

209. 长度最小的子数组 中等 1.8K

209. 长度最小的子数组 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 209. 长度最小的子数组 https://leetcode.cn/problems/minimum-size-subarray-sum/description/ 完成情况&#xff1a; 解题思路&#xff1…

单表操作、查询

十四、单表的增删改查&#xff08;DML语句&#xff09; CRUD&#xff08;增删改查&#xff09; 为空要用is null is not null &#xff0c;不能写null <>为等于&#xff0c;也可以为is <>不等于 十五、单表复杂查询 select语句及关系运算符 除了数字&#x…

ROS学习篇之传感器(三)激光雷达

文章目录 一.确定雷达的型号二.安装驱动1.新建一个工作空间"lidar_ws"&#xff08;随便一个你存放代码的地方&#xff09;2.clone下驱动的源代码&#xff08;在lidar_ws/src目录下&#xff09;3.尝试编译一下&#xff08;在lidar_ws目录下&#xff09; 四.在RVIZ中的…

redis的四种模式优缺点

redis简介 Redis是一个完全开源的内存数据结构存储工具&#xff0c;它支持多种数据结构&#xff0c;以及多种功能。Redis还提供了持久化功能&#xff0c;可以将数据存储到磁盘上&#xff0c;以便在重启后恢复数据。由于其高性能、可靠性和灵活性&#xff0c;Redis被广泛应用于…

JavaSwing+MySQL的医药销售管理系统

点击以下链接获取源码&#xff1a; https://download.csdn.net/download/qq_64505944/88108217?spm1001.2014.3001.5503 JDK1.8 MySQL5.7 功能&#xff1a;用户管理&#xff0c;药品库存管理&#xff0c;进销管理&#xff0c;营销管理

产品解读|有了JMeter,为什么还需要MeterSphere?

提起JMeter&#xff0c;相信大部分的测试人员应该都很熟悉。JMeter因其小巧轻量、开源&#xff0c;加上支持多种协议的接口和性能测试&#xff0c;在测试领域拥有广泛的用户群体。一方面&#xff0c;测试人员会将其安装在个人的PC上&#xff0c;用以满足日常测试工作的需要&…

【Claude2体验】继ChatGPT,文心一言,Bing等大模型后,初次对话Claude2的体验

文章目录 &#x1f33a;注意事项&#x1f916;什么是Claude2⭐与之前版本的进步&#x1f6f8;官网的讲解&#x1f354;功能介绍&#x1f384;使用体验&#x1f386;查看不知道如何才能打开的文档 的内容&#x1f386;日常需求✨Claude✨ChatGPT3.5 &#x1f916;总结 &#x1f…

CC1310F128系列 超低功耗低于1GHz射频 微控制器芯片

CC1310F128 是一款经济高效型超低功耗低于1GHz射频器件&#xff0c;凭借极低的有源射频和MCU电流消耗以及灵活的低功耗模式&#xff0c;CC1310F128可确保卓越的电池寿命&#xff0c;并能够在小型纽扣电池供电的情况下以及在能量采集应用中实现远距离工作。 改芯片有三个后缀&am…

redis-cluster 创建及监控

集群命令 cluster info&#xff1a;打印集群的信息。 cluster nodes&#xff1a;列出集群当前已知的所有节点&#xff08;node&#xff09;的相关信息。 cluster meet <ip> <port>&#xff1a;将ip和port所指定的节点添加到集群当中。 cluster addslots <slot…

小程序商城免费搭建之java商城 java电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

libhv之hloop_process_ios源码分析

上一篇文章对hloop源码大概逻辑和思想进行了一个简单的分析&#xff0c;其中主要涉及三类&#xff08;timer>io>idles&#xff09;事件处理。下面将对hloop_process_ios事件做一下简单的分析。 int hloop_process_ios(hloop_t* loop, int timeout) {// That is to call …

vr禁毒毒驾模拟体验从源头拒绝毒品,预防毒品

俗话说&#xff0c;一念天堂&#xff0c;一念地狱。吸毒一口&#xff0c;掉入虎口。吸毒对人体的危害非常大&#xff0c;普通人吸毒会导致家破人亡&#xff0c;明星吸毒会毁掉自己的大好星途。没有感同身受&#xff0c;何来悲喜相通&#xff0c;毒品危害认知VR模拟情景体验是VR…