热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MySQL多表数据库操作方法及子查询详解

本文详细介绍了MySQL数据库的多表操作方法,包括增删改和单表查询,同时还解释了子查询的概念和用法。文章通过示例和步骤说明了如何进行数据的插入、删除和更新操作,以及如何执行单表查询和使用聚合函数进行统计。对于需要对MySQL数据库进行操作的读者来说,本文是一个非常实用的参考资料。

本文目录:

一、数据增删改

增加数据

insert [into] 表名[(可选字段名)] values(一堆值1),(一堆值2),.....

into 可以省略

表名后的字段可以选

如果写了 后面的values中的值必须与表名后的字段一一对应

如果没写 后面的values中的值必须与表的所有字段一一对应

values后面可以给多组值 用逗号隔开

删除数据

delete from 表名[where条件]

条件不写 是删除所有记录 是一行一行删除 注意自增id 不会归零

truncate 重建表 先记录表结构 删除整个表再重新建出来表 自增id 会归零

更新数据

update 表名 set 字段名 = 值[,字段2 = 值2],[where条件]

可以一次性修改多个字段的值用逗号隔开

条件如果不写 修改所有记录

二、单表查询

不带关键字的查询select {1.*|2.字段名|3.运算|4.聚合函数} from 表名 [where条件]1.*表示查询所有字段2.可以手动要查询的字段3.字段的值可以进行加减乘除运算4.聚合函数,用于统计where 是可选的

数据准备1:

create table stu(id int primary key auto_increment,name

char(10),math float,english float);

insert into stu values(null,"赵云",90,30);

insert into stu values(null,"小乔",90,60);

insert into stu values(null,"小乔",90,60);

insert into stu values(null,"大乔",10,70);

insert into stu values(null,"李清照",100,100);

insert into stu values(null,"铁拐李",20,55);

insert into stu values(null,"小李子",20,55);

关键字的作用

distinct 去除重复数据 所有数据全都重复才算重复where在逐行读取数据时的一个判断条件

group by 对数据分组

having 对分组后的数据进行过滤

order by 对结果排序

by 后面可以有多个排序依据

limit 指定获取数据条数

limit 限制显示条数

limit a,b

limit 1,5

从1开始 到5结束 错误

从1开始 不包含1 取5条

分页查询

每页显示3条  共有10条数据

if 10 % 3 == 0:

10 / 3

else:

10/3 +1

总页数4

第一页

select *from emp limit(0,3)

第二页

select *from emp limit(3,3)

第二页

select *from emp limit(6,3)

起始位置的算法

页数 - 1 * 条数

1 - 1 = 0 * 3 = 0

2 - 1 = 1 * 3 = 3

栗子1:查询去重后所有学生的名字

d1e5429b3a2f2d00adcd948bde4f995a.png

栗子2:获取大乔的数学与英语的成绩

c5e88c4b7a212ac5ae991f4ebf4a51d2.png

栗子3:对全班数学分数做升序排列(order by后面不加默认升序)

a5e86b35b785da39a94cb112356da017.png

栗子4:对全班英语分数做降序排列(升序asc,降序desc)

3c9179e1b3253c73f7c87a63d284de57.png

栗子5:获取英语成绩为55分的第一条记录

b5fa5aa71fbf81380b9ea9ea27ea0a9b.png

完整的select 语句 语法 *****

select [distinct] * from表名

[wheregroup by

having

order by

limit

]

注意 在书写时 必须按照这个顺序来写 但是顺写不代表执行顺序

数据库伪代码

deffrom():

打开文件

defwhere():

对读取的数据进行过滤

def group_by():

对数据分组

def having():

对分组后的数据进行过滤

def distinct():

去除重复数据

def order():

排序

def limit():

指定获取条数select 语句的执行顺序 *****defselect(sql):

data= from()

data= where(data)

data=group by(data)

data=having(data)

data=distinct(data)

data= orderby(data)

data=limit(data)return data;

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

concat()函数用于拼接字符串select(casewhen english+ math > 120then

concat(name,"nice")

when english&#43; math <&#61; 130then

concat(name,"shit")

end

) ,english,mathfrom stu; *完全不重要

拓展

数据准备2&#xff1a;

create table emp (id int,name char(10),sex char,dept char(10),job

char(10),salary double);

insert into emp values

(1,"刘备","男","市场","总监",5800),

(2,"张飞","男","市场","员工",3000),

(3,"关羽","男","市场","员工",4000),

(4,"孙权","男","行政","总监",6000),

(5,"周瑜","男","行政","员工",5000),

(6,"小乔","女","行政","员工",4000),

(7,"曹操","男","财务","总监",10000),

(8,"司马懿","男","财务","员工",6000);

group by 分组查询

什么是分组&#xff1f;

把一个整体 分割为多个部分

为什么分组&#xff1f;

在数据库中分组为了统计&#xff0c;分组后 组里的详细记录就被隐藏起来了 不能直接查看

什么样的字段适合用于分组&#xff1f;

重复性高的字段

注意:1.只有出现在group by 后面的字段 才可以被显示 其他都被影藏。2.聚合函数不能写在where的后面 where最先执行 它的作用硬盘读取数据

并过滤 以为数据还没有读取完 此时不能进行统计。

dept 一分组 变成三条记录 每个组中却包含多条记录 没办法显示&#xff0c;一定要显示的话&#xff0c; 可以使用group_concat(字段名)&#xff0c; 可以将多个值拼接成一个字符串。

栗子1&#xff1a;请查询每种性别的平均工资(性别分组)

e53f4beee2b73b27269ec5bdeaa83610.png

栗子2&#xff1a;请查询每种岗位的平均工资( 岗位分组)

f2ae6ef68456286b7a5c6bee0cb27e03.png

了解&#xff1a;

在mysql5.6中 分组后会默认显示 每组的第一条记录 这是没有意义的5.7不显示 因为5.7中 sql_mode中自带 ONLY_FULL_GROUP_BY

group by 后面可以有多个分组与依据 会按照顺序执行

三、正表达式匹配

由于like只能使用% 和 _ 不太灵活(_&#xff1a;表示任意单个字符。匹配单个任意字符&#xff0c;它常用来限制表达式的字符长度语句&#xff1a;(可以代表一个中文字符))

可以将like换为 regexp 来使用正则表达式

常用表达式&#xff1a;

40e22bbb0b42c9fe4c5d5c347c353228.png

栗子1&#xff1a;查询名字为司开头的员工记录

d45c019c4b5092d38a79ae84526099e3.png

栗子2&#xff1a;查询部门名字为务结尾的所有人记录

46520ac6219638ff7938546e73508a83.png

栗子3&#xff1a;匹配语句中有“l”

60ca6db54b583fbc5f5bcaa956bd9c87.png

(未完待续&#xff01;)

四、多表查询

数据准备3&#xff1a;

insert emp values(1,"大黄","m",1);

insert emp values(2,"老王","m",2);

insert emp values(3,"老李","w",3);

create table dept (

id int,

name char(10)

);

insert dept values(1,"市场");

insert dept values(2,"财务");

insert dept values(3,"行政");

1.笛卡尔积查询

select *from 表1,表n

89cc2c7c0660bf261f05c194688d692d.png

查询结果是

将坐标中的每条记录 与右表中的每条记录都关联一遍

因为 他不知道什么样的对应关系是正确 只能帮你都对一遍

a表有m条记录  b表有n条记录

笛卡尔积结果为m * n 记录

需要自己筛选出正确的关联关系

select *from emp,dept where emp.dept_id &#61; dept.id;

2.内连接查询 就是笛卡尔积查询

select *from emp [inner] join dept;

c81f89d92d450a8446d529e73edb20f9.png

select * from emp inner join dept where emp.dept_id &#61; dept.id;

eff586a0d9fdd7c46b35861484ece3e4.png

3.左外链接查询

select * from emp left join dept on emp.dept_id &#61; dept.id;

左表数据全部显示   右表只显示匹配上的

49b08106be223f78493d51da0ff28062.png

4.右外链接查询

select * from emp right join dept on emp.dept_id &#61; dept.id;

右表数据全部显示   左表只显示匹配上的

内和外的理解   内指的是匹配上的数据  外指的是没匹配上的数据

0c8c5897aeb5a02b60a9de2588c66a6d.png

5.全外连接

select * from emp full join dept on emp.dept_id &#61; dept.id;  ##mysql不支持

union 合并查询结果

select * from emp left join dept on emp.dept_id &#61; dept.id

union

select * from emp right join dept on emp.dept_id &#61; dept.id;

union 去除重复数据  只能合并字段数量相同的表

union all 不会去除重复数据

on 关键字 where 都是用于条件过滤  没有本质区别

在单表中where的作用是筛选过滤条件

在多表中where 连接多表 满足条件就连接 不满足就不连接

为了区分是单表还是多表  搞个新的名字 就是 on

只要是连接多表的条件 就使用on

三表查询

数据准备4&#xff1a;

create table stu(id int primary key auto_increment,name char(10));

create table tea(id int primary key auto_increment,name char(10));

create table tsr(

id int primary key auto_increment,

t_id int,s_id int,

foreign key(s_id) references stu(id),

foreign key(s_id) references stu(id));

insert into stu values(null,"张三"),(null,"李四");

insert into tea values(null,"egon"),(null,"yyh");

insert into tsr values(null,1,1),(null,1,2),(null,2,2);

select * from stu join tea join tsr

on stu.id &#61; tsr.s_id and tea.id &#61; tsr.t_id

where tea.name &#61; "yyh";

3bbc349880c48b5e9e3da613b587f43e.png

多表查询套路

1.把所有表都连起来

2.加上连接条件

3.如果有别的过滤条件 加上where

五、子查询

什么叫着子查询&#xff1f;

当一个查询的结果是另一个查询的时 这个查询称之为子查询(内层查询)

什么时候使用子查询&#xff1f;

当一次查询无法得到想要结果时 需要多次查询

解决问题的思路&#xff1f;

是把一个复杂的问题 拆分为多个简单的问题

是把一个复杂的查询 拆分为多个简单的查询

in (1,2)

给你部门的的名称

查部门有哪些人?

第一步  查到部门的id

第二步  拿着id去员工表查询

select * from dept join emp on dept.id &#61; emp.dept_id;

select * from emp join

# 使用子查询 得到 每个部门的id 以及部门的 最高工资  形成一个虚拟表 把原始表和 虚拟表连接在一起

(select dept_id,max(salary) as m from emp group by dept_id) as t1

# 如果这个人的部门编号 等于 虚拟表中的部门编号

on emp.dept_id &#61; t1.dept_id

and

# 并且 如果这个人的工资 等于 虚拟表中的最高工资  就是你要找的人

emp.salary &#61; t1.m;

参考资料&#xff1a;

https://www.cnblogs.com/wicub/p/5694856.html

https://www.cnblogs.com/mr-wuxiansheng/p/11188503.html



推荐阅读
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • mysql-cluster集群sql节点高可用keepalived的故障处理过程
    本文描述了mysql-cluster集群sql节点高可用keepalived的故障处理过程,包括故障发生时间、故障描述、故障分析等内容。根据keepalived的日志分析,发现bogus VRRP packet received on eth0 !!!等错误信息,进而导致vip地址失效,使得mysql-cluster的api无法访问。针对这个问题,本文提供了相应的解决方案。 ... [详细]
author-avatar
mobiledu2502910233
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有