联表查询相关语法

1.查询sql语句的执行顺序

sql:语法
select distinct * from 左表名
(left/inner/right)join 右表名
on 连接条件
where 筛选条件
group by 分组的列表(按什么字段分组)
having 分组条件 
order by 排序的字段
limit 分页
以上为语法结构,顺序不能乱

执行顺序:

  1. from 左表名
  2. on 连接条件
  3. 连接类型 (inner/left/right) join 右表名
  4. where 筛选条件
  5. group by 分组列表(按什么字段分组)开始使用select中的别名,后面的语句中都可以使用
  6. 聚合函数avg、sum、max、min、count
  7. having having_condition
  8. select
  9. distinct 查询列表(要查询的字段)
  10. order by 排序的字段等
  11. limit limit_number

123步骤先确定要查询的大表;4步骤确定要的记录,去掉不要的记录;56分组并筛选要的;78留下要的字段列;9排序一下;10留下想要的记录数

  • 详解:从上述顺序中不难发现,所有的查询语句都是从from语句开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入。
  1. 首先对from子句中的前两个表执行一个笛卡尔积,此时生成虚拟表vt 1(选中相对小的表做基础表)

  2. 应用on筛选器,on中的逻辑表达式将应用到vt 1 中的各个行,筛选出满足on逻辑表达式的行,生成虚拟表vt 2。

  3. 如果是outer join 那么这一步就将添加外部行,left outer join 就把左表在第二步中过滤的添加进来,如果是right outer join 那么就将右表在第二步中过滤掉的行添加进来,这样生成虚拟表 vt 3 。

  4. 如果 from 子句中的表数目多余两个表,那么就将vt 3和第三个表连接从而计算笛卡尔乘积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表 vt 3。

  5. where筛选器,对上一步生产的虚拟表引用where筛选器,生成虚拟表 vt 4

    注意where和on的区别:先执行on,后执行where;on是建立关联关系,在生成临时表时执行;where是在临时表生成后对数据进行筛选的

  6. group by子句将列中的唯一的值组合成为一组,得到虚拟表 vt 5。如果应用了 group by ,那么后面是所有步骤都只能得到vt 5 的列或聚合函数,原因在于最终的结果集中只为每一个组包含一行从这一步开始才可以使用select中的别名,他返回的是一个游标,而不是一个表,所以在where中不可以使用select中的别名,而having却可以使用

  7. 聚合函数,为vt 5生成超组,生成vt 6

  8. having 筛选器,生成vt 7,having筛选器是第一个也是唯一一个应用到已分组数据的筛选器

  9. 处理select子句,将vt 7中的select中出现的列筛选出来,生成 vt 8

  10. distinct,对vt 8进行去重,生成vt 9

  11. order by,按照排序条件排序 vt 9,此时返回的一个游标,而不是虚拟表

  12. limit ,生成 vt 10 返回结果给请求者即用户

outer join:完全外连接,返回左表和右表的所有行

left (outer)join:左外连接,返回匹配条件的行和左表的所有行

right(Outer)join:右外连接,返回匹配条件的行和右表的所有行

笛卡尔积: 假设A和B是两个集合,存在一个集合,它的元素是用A中元素为第一元素,B中元素为第二元素构成的有序二元组,这个集合称为集合A和集合B的笛卡尔积,记为A X B。

2.联表查询

多表联合查询:同时查询两个或两个以上的表

why:当我们查询的结果不在一张表中,就需要联表查询

联表查询的种类:

  • 内连接:查询两个表中公共部分
  • 外连接
    • 左外连接:查询左边中所有的内容以及公共内容
    • 右外连接:查询右边中所有的内容以及公共内容
  • 自连接:自己和自己连接

2.1表与表之间的关系

  1. 表与表之间有联系:外键
  2. 表与表之间的关系:
    • 多对一(n : 1):员工表和部门表**外键放置在多那方**
    • 多对多(n : n):学生和课程设置一个中间表,用来存放两个外键,即两张表的主键
    • 一对一(1 : 1)

2.2内连接

  • 语法
Select * from 左表名 
inner from 右表名
on 联表条件
-- 查询员工信息以及员工对应的部门信息。(我们查询的内容不在一张表中 需要联表查询)
-- select * from 表1 inner join 表2 on 联表条件
select * from tb_emp inner join tb_dept; -- 如果没有联表条件 则会出现笛卡尔积
-- 如何得到结果不在一张表中,就需要联表查询。
select * from tb_emp inner join tb_dept on tb_emp.dept_id=tb_dept.id;select e.*,d.name dname from tb_emp e inner join tb_dept d on e.dept_id=d.id

2.3左外连接

  • 语法
select * from 左表名
left join 右表名
on 联表条件
-- 查询员工信息以及对应部门得信息 没有部门的员工也显示。
select * from tb_emp e left join tb_dept d on e.dept_id=d.id

2.4右外连接

  • 语法
select * from 左表名
right join 右表名
on 联表条件
-- 查询员工信息以及对应部门得信息 显示没有员工的部门信息
select * from tb_emp e right join tb_dept d on e.dept_id=d.id;

2.5自连接

  • 自己连接自己的表,连接类型为上述三种
-- 查询员工姓名以及对应的领导名字
select yg.name 员工姓名,ld.name 领导名 from tb_emp yg inner join tb_emp ld on yg.managerid=ld.id-- -- 查询员工姓名以及对应的领导名字 显示没有领导员工信息
select yg.name 员工姓名,ld.name 领导名 from tb_emp yg left join tb_emp ld on yg.managerid=ld.id

3.嵌套查询

把一个sql查询的结果作为另一个sql查询的条件的值

例子: 查询研发部的员工信息。

【1】查询研发部的部门号 【2】根据查询的部门号查询对应的员工信息

select * from tb_emp where dept_id=(
select id from tb_dept where name='研发部')

例子: 查询研发部,市场部的员工信息

select * from tb_emp where dept_id in(
select id from tb_dept where name='研发部' or name='市场部')

例子: 查询薪资最高的员工信息。

select * from tb_emp where salary=(
select max(salary) from tb_emp);

4.把查询的结果作为一个临时表

例子: 查询各个部门中最高薪资的员工信息

select e.* from tb_emp e inner join
(select max(salary) m,dept_id from tb_emp group by dept_id) ton e.dept_id=t.dept_id and e.salary=t.m

5. mysql中内置的函数

mysql里面存在了很多函数方法,字符串函数,时间函数,数学函数等。

5.1字符串函数

操作字符串

函数功能
concat(s1,s2,…sn)字符串拼接,将s1,s2,…sn拼接成一个字符串
lower(string)将字符串全部转为小写
upper(string)将字符串全部转为大写
lpad(string,n,pad)左填充,用字符串pad对string的左边进行填充,达到n个字符串长度
rpad(string,n,pad)右填充,用字符串pad对string的右边进行填充的,达到n个字符串长度
trim(string)去掉字符串头部和尾部的空格
substring(string,start,len)返回从字符串string的start位置起的len个长度的字符串
char_length(string)返回字符串的长度
-- concat()字符串拼接
select name,concat('hello',name,'吃吗',salary) from tb_emp;
-- upper(str)转化为大写字母
select name, upper(name) from tb_emp;
-- lpad左填充 
select name,rpad(name,2,'A') from tb_emp;
-- trim()去除左右空格
select name,trim(name) from tb_emp;
-- substring()截取字符串 下标从1开始
select name,substring(name,1,1)from tb_emp;
-- 姓灭
select * from tb_emp where substring(name,1,1)='灭'
-- char_length 求字符串的长度
select name,char_length(name) from tb_emp;
-- 求名字长度为3
select * from tb_emp where char_length(name)=3

5.2 日期函数

函数功能
curdate()返回当前日期
curtime()返回当前时间
now()返回当前日期和时间
year(date)获取指定date的年份
month(date)获取指定date的月份
day(date)获取指定date的日期
date_add(date,interval expr type)返回一个日期/时间值加上一个时间间隔expr后的时间值
datediff(date 1,date 2)返回起始时间date 1和结束时间date 2之间的天数
-- 查找今天入职的员工信息
select * from tb_emp where entrydate=curdate()
-- 当前日期
select entrydate,curdate(),curtime(),now(),year(entrydate),month(entrydate) from tb_emp;-- date_add(日期数据,interval 值 单位) : 单位:year month day hour  MINUTE second
select entrydate,date_add(entrydate,INTERVAL 1 year) from tb_emp;-- datediff 两个日期的相差的天数
select entrydate, datediff(now(),entrydate) from tb_emp;

5.3 数学函数

函数功能
ceil(x)向上取整
floor(x)向下取整
mod(x,y)返回x/y的模
abs(x)求某个数的绝对值
-- 查询最近1月的订单 
select salary,ceil(salary),floor(salary),RAND()*10 from tb_emp;

6. 查询存在一个表而不在另一个表中的数据

问题描述: A、B两表,找出ID字段中,存在A表,但是不存在B表的数据。A表总共13w数据,去重后大约3W条数据,B表有2W条数据,且B表的ID字段有索引。

  • 方法一: 使用 not in ,容易理解,效率低 ~执行时间为:1.395秒
1 select distinct A.ID from  A where A.ID not in (select ID from B)
  • 方法二: 使用 left join…on… , “B.ID isnull” 表示左连接之后在B.ID 字段为 null的记录 ~执行时间:0.739秒
1 select A.ID from A left join B on A.ID=B.ID where B.ID is null
  • 方法三: 逻辑相对复杂,但是速度最快 ~执行时间: 0.570秒
select * from  A where (select count(1) from B where A.ID=B.ID) = 0 

方法三完美!由于数据量大,方法一,二,根本打不开

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《Django 5 By Example》读后感

一、 为什么选择这本书? 本人的工作方向为Python Web方向,想了解下今年该方向有哪些新书出版,遂上packt出版社网站上看了看,发现这本书出版时间比较新(2024年9月),那就它了。 从2024年11月11日至2024年12月18日期间&…

TouchGFX移植(3)增加SDRAM驱动

一)SDRAM驱动增加到工程中 1)加入驱动sdram.c文件,文件在上节课里有源代码。 2)在fmc.c文件里指定位置增加代码 SDRAM_Init();另外需要包含文件:#include “sdram.h” /* USER CODE BEGIN 0 / #include “sdram.h” …

Apache Kylin最简单的解析、了解

官网:Overview | Apache Kylin 一、Apache Kylin是什么? 由中国团队研发具有浓厚的中国韵味,使用神兽麒麟(kylin)为名 的一个OLAP多维数据分析引擎:(据官方给出的数据) 亚秒级响应&#xff…

【Token】校验、会话技术、登录请求、拦截器【期末实训】实战项目学生和班级管理系统\Day15-后端Web实战(登录认证)\讲义

登录认证 在前面的课程中,我们已经实现了部门管理、员工管理的基本功能,但是大家会发现,我们并没有登录,就直接访问到了Tlias智能学习辅助系统的后台。 这是不安全的,所以我们今天的主题就是登录认证。 最终我们要实现…

前端(组件传参案例)

父组件(商品详情页) 子组件上边放大图 底下缩小轮播图 需求分析:父组件获取图片数据,传给底下子组件进行进行轮播,实现父组件给子组件传参。然后底下子组件轮播后,把当前图片下标给父组件,实现子组件给父组件传参。父组…

【Linux网络编程】第十二弹---构建与优化HTTP请求处理:从HttpRequest到HttpServer的实战

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【Linux网络编程】 目录 1、HttpRequest类 1.1、基本结构 1.2、构造析构函数 1.3、反序列化函数 1.4、GetLine() 1.5、打印函数…

使用k6进行kafka负载测试

1.安装环境 kafka环境 参考Docker搭建kafka环境-CSDN博客 xk6-kafka环境 ./xk6 build --with github.com/mostafa/xk6-kafkalatest 查看安装情况 2.编写脚本 test_kafka.js // Either import the module object import * as kafka from "k6/x/kafka";// Or in…

Linux内存管理 --- 进程创建虚拟地址的过程

文章目录 前言一、进程虚拟地址空间二、进程号1的创建过程2.1 kernel_init2.2 kernel_execve2.2.1 alloc_bprm2.2.2 bprm_stack_limits2.2.3 copy_string_kernel2.2.4 bprm_execve 2.3 bprm_execve2.3.1 prepare_binprm2.3.2 load_binary2.3.3 interpreter 三、load_elf_binary…

uniapp blob格式转换为video .mp4文件使用ffmpeg工具

前言 介绍一下这三种对象使用场景 您前端一旦涉及到文件或图片上传Q到服务器,就势必离不了 Blob/File /base64 三种主流的类型它们之间 互转 也成了常态 Blob - FileBlob -Base64Base64 - BlobFile-Base64Base64 _ File uniapp 上传文件 现在已获取到了blob格式的…

springboot447教师薪酬管理系统(论文+源码)_kaic

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理,然而,随着近些年信息技术的迅猛发展,让许多比较老套的信息管理模式进行了更新迭代,老师信息因为其管理内容繁杂,管理数量繁多导致手工进行处理不能满足广…

三、ubuntu18.04安装docker

1.使用默认ubuntu存储库安装docker 更新软件存储库 更新本地软件数据库确保可以访问最新版本。打开终端输入:sudo apt-get update 卸载旧版本的docker 建议继续之前卸载任何旧的docker软件。打开终端输入:sudo apt-get remove docker docker-engine …

Java JDK8之前传统的日期时间-Date、SimpleDateFormat、Calendar

1. Date (1) Date代表的是日期和时间 (2) 常见构造器和常用方法 构造器说明public Date()创建一个Date对象,代表系统当前日期和时间public Date(long time)根据传入的时间毫秒值创建一个Date对象 方法说明public long getTime()返回从1970.1.1 00:00:00到此时的毫…

powershell(1)

免责声明 学习视频来自 B 站up主泷羽sec,如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识,以下代码、网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 泷羽sec官网:http…

matlab绘图时设置左、右坐标轴为不同颜色

目录 一、需求描述 二、实现方法 一、需求描述 当图中存在两条曲线,需要对两条曲线进行分别描述时,应设置左、右坐标轴为不同颜色,并设置刻度线,且坐标轴颜色需要和曲线颜色相同。 二、实现方法 1.1、可以实现: 1…

初学stm32 --- 窗口看门狗

STM32F1 窗口看门狗 窗口看门狗(WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在 T6 位(WWDG->CR 的第六位)变成 0 前被刷新,看门狗电…

Kafka Streams 在监控场景的应用与实践

作者:来自 vivo 互联网服务器团队- Pang Haiyun 介绍 Kafka Streams 的原理架构,常见配置以及在监控场景的应用。 一、背景 在当今大数据时代,实时数据处理变得越来越重要,而监控数据的实时性和可靠性是监控能力建设最重要的一环…

论文笔记:是什么让多模态学习变得困难?

整理了What Makes Training Multi-modal Classification Networks Hard? 论文的阅读笔记 背景方法OGR基于最小化OGR的多监督信号混合在实践中的应用 实验 背景 直观上,多模态网络接收更多的信息,因此它应该匹配或优于其单峰网络。然而,最好的…

【鸿蒙实战开发】HarmonyOS状态管理之@Link

前言 在前面两篇状态管理相关的文章中,我们分别讲解了 State 和 Prop 两个状态管理装饰器的作用和基本使用。State 状态管理装饰器是最基本的状态管理装饰器,组件使用其修饰的变量,组件的更新可以随着变量的变化而更新;Prop 状态…

Nginx常用配置详解(1)

Nginx常用配置详解 一、全局块(main)配置 在Nginx的配置文件中,最外层的部分是全局块。这部分配置通常会影响Nginx服务器整体的运行参数。 worker_processes 作用:这个配置指令用于指定Nginx工作进程的数量。工作进程是Nginx处理…

NVIDIA发布紧凑型生成式AI超级计算机:性能提升,价格更低

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…