MySQL

通用语法及分类

分类全称说明
DDLData Definition Language数据定义语言
DMLData Manipulation Language数据操作语言
DQLData Query Language数据查询语言
DCLData Control Language数据控制语言

DDL

数据库操作

查询所有数据库:

show databases;

创建数据库:

create database if not exists [数据库名];

删除数据库:

drop database if exists [数据库名];

查询当前数据库:

select database();
表操作

查询当前数据库所有表:

show tables;

创建表:

mysql> create table tb_user(
    -> id int comment '编号',
    -> name varchar(50) comment '姓名',
    -> age int comment '年龄',
    -> gender varchar(4) comment '性别'
    -> ) comment '用户表';


create table score(
     id int auto_increment,
     name varchar(30) comment '姓名',
     chinese int comment '语文成绩',
     math int comment '数学成绩',
     english int comment '英语成绩',
     primary key (id)
     ) comment  = '成绩表';

查询表结构:

DESC [表名];
或者:
show create table [表名];

添加字段:

ALTER TABLE [表名] ADD [字段名] 类型(长度) COMMENT '注释';
例如:ALTER TABLE employee ADD nickName varchar(20) comment '昵称';

修改字段:

1.修改数据类型
ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度);
例如:
ALTER TABLE employee MODIFY name varchar(30);

2.修改字段名和字段类型
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [COMMENT 注释] [约束];
例如:
ALTER TABLE employee CHANGE nickName username varchar(30) COMMENT '用户名';

删除字段:

ALTER TABEL 表名 DROP 字段名;
例如:
ALTER TABLE employee DROP username;

修改表名:

ALTER TABLE 表名 RENAME TO 新表名;
例如:
ALTER TABLE employee RENAME TO emp;

删除表:

1.删除表 
DROP TABLE [IF EXISTS] 表名;
例如:
DROP TABLE IF EXISTS tb_user;

2.删除指定表,并重新创建该表(原表数据会全部清空,只留下表结构)
TRUNCATE TABLE 表名;
例如:
truncate table emp;

DML

添加数据

1.给指定字段添加数据:

INSERT INTO 表名(字段名1,字段名2,...)VALUES (值1,值2,...);

2.给全部字段添加数据:

INSERT INTO 表名 VALUES (值1,值2,...);
修改数据
UPDATE 表名 SET 字段名1 = 值1,字段名1 = 值2,... WHERE 条件;
例如:
update emp SET employeeId = '957',name = '腿哥' WHERE ID = 1;
删除数据
DELETE FROM 表名 WHERE 条件;
例如:
DELETE FROM emp WHERE AGE = 24;

DQL

基础查询
SELECT * FROM 表名;
例如:select * from emp;

SELECT 字段1,字段2,... FROM 表名;
例如:SELECT NAME,AGE FROM emp;

SELECT 字段1 AS 别名 FROM 表名;(AS可省略)
例如:select employeeid '职业id' from emp;
条件查询
SELECT 字段列表 FROM 表名 WHERE 条件列表;

--查询性别为null的员工(关键字:is)
select * from emp where gender is null;

--查询年龄处于25-28的员工(关键字:and)
select * from emp where age>=25 and age<=28;

--查询性别为女且年龄为18的员工
select * from emp where gender = '女' and age = 18;

--查询年龄为18或者26的员工(关键字:in)
方式一:select * from emp where age = 18 or age = 26;
方式二:select * from emp where age in(18,26);

--查询姓名长度为2的员工(关键字:like,外加2个下划线)
select * from emp where name like '__';

--查询employeeID以'U'开头的员工(关键字:%)
select * from emp where employeeid like 'U%';
聚合函数

介绍:将一列数据作为一个整体,进行纵向计算

常见聚合函数:

函数功能
count统计数量
max最大值
min最小值
avg平均值
sum求和
语法:SELECT 聚合函数(字段列表) FROM 表名;
注意:null值不参与所有聚合函数运算。

--统计员工数量
SELECT COUNT(*) FROM EMP;

--统计员工平均年龄
SELECT AVG(AGE) FROM EMP;

--统计员工的最大年龄
SELECT max(age) from emp;

--统计入职日期为2023年8月18日的员工年龄之和
select sum(age) from emp where hireDate = '2023-08-18';
分组查询

1.语法

SELECT 字段列表 FROM 表名 [WHERE 条件] GROUP BY 分组字段名 [HAVING 分组后过滤条件];

2.where与having的区别

执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;
而having是分组之后对结果进行过滤。

判断条件不同:where不能对聚合函数进行判断,而having可以。

3.例子

--1.根据性别分组查询
select gender, count(*) from emp group by gender;

--2.根据性别分组,统计各组员工的平均年龄
select gender, avg(age) from emp group by gender;

--3.查询年龄小于26,并根据入职日期分组,获取员工数量大于等于3的入职日期
select hireDate,count(*)hireDateCount from emp where age < 26 group by hireDate having hireDateCount >= 3;
排序查询

1.语法

SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1, 字段2 排序方式2;

2.例子

--1.根据年龄对员工进行升序排序
select * from emp order by age asc;

--2.根据入职时间对员工进行降序排序
select * from emp order by hireDate desc;

--3.根据年龄对员工进行降序排序,若年龄相同,再按照入职时间降序排序
select * from emp order by age desc,hireDate desc;
分页查询

1.语法

SELECT 字段列表 FROM 表名 LIMIT 起始索引,查询记录数;
其中:起始索引 = (页码 - 1)* 页展示记录数。

2.例子

--1.查询第一页员工数据,每页展示5条记录
select * from emp limit 0,5;

--2.查询第二页员工记录,每页展示5条记录 
select * from emp limit 5,5;

--有limit和order by,先order by 再到 limit
select * from emp where age >23 and age <= 26 order by age asc,hireDate asc limit 0,5;

函数

字符串函数
函数功能
concat(s1, s2, ... sn)字符串拼接,将s1,s2,... 拼接成一个字符串
lower(str)将字符串str全部转为小写
upper(str)将字符串str全部转为大写
lpad(str, n, pad)左填充,用字符串pad对str的左边进行填充,达到n个字符串长度
rpad(str, n, pad)右填充,用字符串pad对str的右边进行填充,达到n个字符串长度
trim(str)去掉字符串头部和尾部的空格
substring(str, start, len)返回从字符串str从start位置起的len个长度的字符串

例子:

语法:SELECT 函数(参数);

SELECT concat('hcy-','henshuai');
+---------------------------+
| concat('hcy-','henshuai') |
+---------------------------+
| hcy-henshuai              |
+---------------------------+

mysql> select lower('HCY');
+--------------+
| lower('HCY') |
+--------------+
| hcy          |
+--------------+

mysql> select upper('hcy');
+--------------+
| upper('hcy') |
+--------------+
| HCY          |
+--------------+

mysql> select lpad('hcy', 5, '-');
+---------------------+
| lpad('hcy', 5, '-') |
+---------------------+
| --hcy               |
+---------------------+

mysql> select rpad('hcy', 5, '-');
+---------------------+
| rpad('hcy', 5, '-') |
+---------------------+
| hcy--               |
+---------------------+

mysql> select trim('  hcy  hen  shuai  ');
+-----------------------------+
| trim('  hcy  hen  shuai  ') |
+-----------------------------+
| hcy  hen  shuai             |
+-----------------------------+

mysql> select substring('hello world', 1, 5);
+--------------------------------+
| substring('hello world', 1, 5) |
+--------------------------------+
| hello                          |
+--------------------------------+

应用案例

--将员工工号统一为9位数,不足在左边填充0
update emp set employeeId = lpad(employeeId, 9 ,0);

mysql> select * from emp;
+------+------------+----------+--------+------+--------------+------------+
| id   | employeeId | name     | gender | age  | idCardNumber | hireDate   |
+------+------------+----------+--------+------+--------------+------------+
|    1 | 000000957  | 腿哥     | 男     |   23 | 454545454545 | 2023-08-17 |
|    1 | 000000957  | 腿哥     | 男     |   23 | 454545454545 | 2023-08-17 |
|    1 | 000000957  | 腿哥     | 男     |   23 | 454545454545 | 2023-08-17 |
|    1 | 000000957  | 腿哥     | 男     |   23 | 454545454545 | 2023-08-17 |
|    1 | 000000957  | 腿哥     | 男     |   23 | 454545454545 | 2023-08-18 |
|    3 | 000000369  | 白家浩   | 男     |   25 | 008          | 2022-02-28 |
|    4 | 000000UZI  | 简自豪   | 男     |   26 | 006          | 2023-08-18 |
|    5 | clearlove  | 厂长     | NULL   |   28 | NULL         | NULL       |
|    6 | 000mayumi  | 马来靓女 | 女     |   18 | 818          | 2023-08-18 |
+------+------------+----------+--------+------+--------------+------------+
数值函数
函数功能
ceil(x)向上取整
floor(x)向下取整
mod(x, y)返回x/y的模(可以用%表示,实际是求余数)
rand()返回0~1内的随机数
round(x, y)求参数x的四舍五入的值,保留y位小数

应用案例

--通过数据库函数,生成一个六位数的随机验证码。
select lpad(round(rand()*1000000,0), 6, '0');

1.首先用rand()生成随机数,并*1000000;
2.用round()函数四舍五入,保留0位小数;
3.用lpad()函数对不足6位的数据在左边填充0;
日期函数
函数功能
curdate()返回当前日期
curtime()返回当前时间
now()返回当前日期和时间
year(date)获取指定date的年份
month(date)获取指定date的月份
day(date)获取指定date的日期
date_add(date, interval expr type)返回一个日期/时间值加上一个时间间隔expr后的时间值
datediff(date1, date2)返回起始时间date1和结束时间date2之间的天数

应用案例

--date_add
mysql> select date_add(now(), interval 90 day);
+----------------------------------+
| date_add(now(), interval 90 day) |
+----------------------------------+
| 2023-11-21 14:21:40              |
+----------------------------------+

--datediff
mysql> select datediff('20230823', '20211225');
+----------------------------------+
| datediff('20230823', '20211225') |
+----------------------------------+
|                              606 |
+----------------------------------+

--查询所有员工的入职天数,降序排序
select name, datediff(curdate(), hireDate) datediff from emp order by datediff desc;
+----------+----------+
| name     | datediff |
+----------+----------+
| 白家浩   |      541 |
| 腿哥     |        6 |
| 腿哥     |        6 |
| 腿哥     |        6 |
| 腿哥     |        6 |
| 腿哥     |        5 |
| 简自豪   |        5 |
| 马来靓女 |        5 |
| 厂长     |     NULL |
+----------+----------+

流程函数
函数功能
if(value, t, f)如果value为true,则返回t,否则返回f
ifnull(value1, value2)如果value1不为空,返回value1,否则返回value2
case when [val1] then [res1] ... else [default] end如果val1为true,返回res1,... 否则返回default默认值
case [expr] when [val1] then [res1] ... else [default] end如果expr的值等于val1,返回res1,... 否则返回default默认值

应用案例

--查询员工姓名和地址,地址按一二线城市划分。
select name, case addr  when '上海' then '一线城市' when '深圳' then '一线城市' 
else '二线城市' end '工作地址' from emp;
+--------+----------+
| name   | 工作地址 |
+--------+----------+
| 白家浩 | 二线城市 |
| 简自豪 | 二线城市 |
| 厂长   | 一线城市 |
| 卡萨   | 一线城市 |
| 林炜翔 | 一线城市 |
| 刘青松 | 一线城市 |
| 金泰相 | 一线城市 |
| 小天   | 一线城市 |
+--------+----------+

约束

约束描述关键字
非空约束限制该字段的数据不能为null。not null
唯一约束保证该字段的所有数据都是唯一,不重复。unique
主键约束主键是一行数据的唯一标识,要求非空且唯一。primary key
默认约束保存数据时,如果未指定该字段的值,则采用默认值。default
检查约束保证字段满足某一条件。check
外键约束用来让两张表的数据之间建立连接,保证数据的一致性和完整性。foreign key
外键约束

语法-添加外键

ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表(主表列名);
例如:
alter table emp add constraint fk_club_id foreign key (club_id) references club(id);

删除外键

ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
例如:
alter table emp drop foreign key fk_club_id;

多表查询

多表关系介绍

一对多

案例:部门和员工的关系。

关系:一个部门对应多个员工,一个员工对应一个部门。

实现:在多的一方建立外键,指向一的一方的主键。

多对多

案例:学生和课程的关系。

关系:一个学生可以选修多门课程。一门课程也可以供多个学生选择。

实现:建立第三张中间表,中间表至少包含两个外键,分别关联两房主键。

一对一

案例:用户和用户详情的关系。

关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率

实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)。

内连接

隐式内连接

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

显式内连接

SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件;

例子

--查询员工姓名,以及关联的部门名称(隐式内连接实现)
mysql> select emp.name,club.name from emp,club where emp.club_id = club.id;
+--------+------+
| name   | name |
+--------+------+
| 白家浩 | JDG  |
| 简自豪 | EDG  |
| 厂长   | EDG  |
| 卡萨   | WBG  |
| 刘青松 | WBG  |
| 林炜翔 | FPX  |
| 金泰相 | LNG  |
| 小天   | TOP  |
+--------+------+

--查询员工姓名,以及关联的部门名称(显式内连接实现)
mysql> select emp.name,club.name from emp inner join club on emp.club_id = club.id;
+--------+------+
| name   | name |
+--------+------+
| 白家浩 | JDG  |
| 简自豪 | EDG  |
| 厂长   | EDG  |
| 卡萨   | WBG  |
| 刘青松 | WBG  |
| 林炜翔 | FPX  |
| 金泰相 | LNG  |
| 小天   | TOP  |
+--------+------+
外连接

左外连接

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

右外连接

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

例子

--查询员工姓名及对应俱乐部名称(左外连接)
mysql> SELECT emp.name, club.name from emp left join club on emp.club_id = club.id;
+--------+------+
| name   | name |
+--------+------+
| 白家浩 | JDG  |
| 简自豪 | EDG  |
| 厂长   | EDG  |
| 卡萨   | WBG  |
| 林炜翔 | FPX  |
| 刘青松 | WBG  |
| 金泰相 | LNG  |
| 小天   | TOP  |
| 小黄人 | NULL |
+--------+------+

--查询俱乐部名称及对应的队员姓名(右外连接)
mysql> select club.name,emp.name from emp right join club on emp.club_id = club.id;
+------+--------+
| name | name   |
+------+--------+
| JDG  | 白家浩 |
| EDG  | 简自豪 |
| EDG  | 厂长   |
| WBG  | 卡萨   |
| WBG  | 刘青松 |
| FPX  | 林炜翔 |
| LNG  | 金泰相 |
| TOP  | 小天   |
| DWG  | NULL   |
+------+--------+
自连接

自连接可以是内连接,也可以是外连接,一定要记得给表取别名。

语法

SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件;
例子:
select a.name '员工', b.name '领导' from emp a left join emp b on a.managerid = b.id;

联合查询

对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。

SELECT 字段列表 FROM 表A
UNION [ALL]
SELECT 字段列表 FROM 表B;

例子

mysql> select * from emp where name like '__'
    -> union
    -> select * from emp where age <25;
+------+--------------+--------+--------+------+--------------+------------+------+---------+
| id   | employeeId   | name   | gender | age  | idCardNumber | hireDate   | addr | club_id |
+------+--------------+--------+--------+------+--------------+------------+------+---------+
|    5 | clearlove    | 厂长   | 男     |   28 | 007          | 2010-12-23 | 深圳 |       2 |
|    6 | Karsa        | 卡萨   | 女     |   18 | 818          | 2023-08-18 | 上海 |       3 |
|    1 | Tian         | 小天   | 男     |   24 | 013          | 2020-11-22 | 上海 |       6 |
|    1 | LWX          | 林炜翔 | 男     |   22 | 888          | 2020-11-22 | 上海 |       4 |
|    7 | xiaohuangren | 小黄人 | 男     |   18 | 999          | 2023-08-25 | 广西 |    NULL |
+------+--------------+--------+--------+------+--------------+------------+------+---------+

mysql> select * from emp where name like '__'
    -> union all
    -> select * from emp where age <25;
+------+--------------+--------+--------+------+--------------+------------+------+---------+
| id   | employeeId   | name   | gender | age  | idCardNumber | hireDate   | addr | club_id |
+------+--------------+--------+--------+------+--------------+------------+------+---------+
|    5 | clearlove    | 厂长   | 男     |   28 | 007          | 2010-12-23 | 深圳 |       2 |
|    6 | Karsa        | 卡萨   | 女     |   18 | 818          | 2023-08-18 | 上海 |       3 |
|    1 | Tian         | 小天   | 男     |   24 | 013          | 2020-11-22 | 上海 |       6 |
|    6 | Karsa        | 卡萨   | 女     |   18 | 818          | 2023-08-18 | 上海 |       3 |
|    1 | LWX          | 林炜翔 | 男     |   22 | 888          | 2020-11-22 | 上海 |       4 |
|    1 | Tian         | 小天   | 男     |   24 | 013          | 2020-11-22 | 上海 |       6 |
|    7 | xiaohuangren | 小黄人 | 男     |   18 | 999          | 2023-08-25 | 广西 |    NULL |
+------+--------------+--------+--------+------+--------------+------------+------+---------+

注意点:

1.对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。

2.union all会将全部的数据直接合并在一起,union会对合并之后的数据去重。

子查询

概念:SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询

SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);

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

根据子查询结果不同,分为:

1.标量子查询(子查询结果为单个值)

2.列子查询(子查询结果为一列)

3.行子查询(子查询结果为一行)

4.表子查询(子查询结果为多行多列)

根据子查询位置,分为:

where之后;

from之后;

select之后。

标量子查询
--查询俱乐部为WBG的员工信息
step1: select id from club where name = 'WBG'
step2: select * from emp where club_id = 3;
select * from emp where club_id = (select id from club where name = 'WBG');

--查询在369选手之后入职的员工信息
step1:select hireDate from emp where name = '白家浩';
step2:select * from emp where hireDate > '2022-02-28';
mysql> select * from emp where hireDate > (select hireDate from emp where name = '白家浩');
+------+--------------+--------+--------+------+--------------+------------+------+---------+
| id   | employeeId   | name   | gender | age  | idCardNumber | hireDate   | addr | club_id |
+------+--------------+--------+--------+------+--------------+------------+------+---------+
|    4 | UZI          | 简自豪 | 男     |   26 | 006          | 2023-08-18 | 湖北 |       2 |
|    6 | Karsa        | 卡萨   | 女     |   18 | 818          | 2023-08-18 | 上海 |       3 |
|    7 | xiaohuangren | 小黄人 | 男     |   18 | 999          | 2023-08-25 | 广西 |    NULL |
+------+--------------+--------+--------+------+--------------+------------+------+---------+


--查询各个俱乐部信息,并统计俱乐部人数
mysql> select c.id, c.name,(select count(*) from emp e where e.club_id = c.id) '人数' from club c;
+------+------+------+
| id   | name | 人数 |
+------+------+------+
|    1 | JDG  |    1 |
|    2 | EDG  |    2 |
|    3 | WBG  |    3 |
|    4 | FPX  |    1 |
|    5 | LNG  |    1 |
|    6 | TOP  |    1 |
|    7 | DWG  |    0 |
+------+------+------+
列子查询

常用的操作符:IN, NOT IN, ANY, SOME, ALL

操作符描述
in在指定的集合范围之内,多选一
not in不在指定的集合范围之内
any子查询返回列表中,有任意一个满足即可
some与any等同,使用some的地方都可以使用any
all子查询返回列表的所有值都必须满足

例子:

--列子查询
--1.查询EDG和WBG的员工信息
--a.查询EDG和WBG的id
mysql> select id from club where name = 'WBG' or name = 'EDG';
+----+
| id |
+----+
|  2 |
|  3 |
+----+
--b.根据id信息,查询员工信息
select * from emp where club_id in(select id from club where name = 'WBG' or name = 'EDG');


--2.查询工资高于WBG所有人的员工信息
--a.查询WBG员工工资
mysql> select salary from emp where club_id = (select id from club where name = 'WBG');
+--------+
| salary |
+--------+
|   6300 |
|  11000 |
+--------+
--b.比WBG全员工资都高的员工信息
mysql> select * from emp where salary > all(select salary from emp where club_id = (select id from club where name = 'WBG'));
+------+------------+--------+--------+------+--------------+------------+------+--------+---------+
| id   | employeeId | name   | gender | age  | idCardNumber | hireDate   | addr | salary | club_id |
+------+------------+--------+--------+------+--------------+------------+------+--------+---------+
|    3 | 369        | 白家浩 | 男     |   25 | 008          | 2022-02-28 | 湖南 |  13800 |       1 |
|    1 | LWX        | 林炜翔 | 男     |   22 | 888          | 2020-11-22 | 上海 |  12000 |       4 |
|    1 | Doinb      | 金泰相 | 男     |   26 | 012          | 2020-11-22 | 上海 |  14000 |       5 |
|    1 | Tian       | 小天   | 男     |   24 | 013          | 2020-11-22 | 上海 |  12520 |       6 |
+------+------------+--------+--------+------+--------------+------------+------+--------+---------+


--3.查询比WBG任一人工资高的员工信息
--a.查询WBG薪资
mysql> select salary from emp where club_id = 3;
+--------+
| salary |
+--------+
|   9800 |
|  11000 |
+--------+
--b.查询比WBG任一人工资高的员工信息
mysql> select * from emp where salary > any(select salary from emp where club_id = 3);
+------+------------+--------+--------+------+--------------+------------+------+--------+---------+
| id   | employeeId | name   | gender | age  | idCardNumber | hireDate   | addr | salary | club_id |
+------+------------+--------+--------+------+--------------+------------+------+--------+---------+
|    3 | 369        | 白家浩 | 男     |   25 | 008          | 2022-02-28 | 湖南 |  13800 |       1 |
|    5 | clearlove  | 厂长   | 男     |   28 | 007          | 2010-12-23 | 深圳 |   9801 |       2 |
|    1 | LWX        | 林炜翔 | 男     |   22 | 888          | 2020-11-22 | 上海 |  12000 |       4 |
|    1 | Crisp      | 刘青松 | 男     |   26 | 777          | 2020-11-22 | 上海 |  11000 |       3 |
|    1 | Doinb      | 金泰相 | 男     |   26 | 012          | 2020-11-22 | 上海 |  14000 |       5 |
|    1 | Tian       | 小天   | 男     |   24 | 013          | 2020-11-22 | 上海 |  12520 |       6 |
+------+------------+--------+--------+------+--------------+------------+------+--------+---------+
行子查询

子查询返回的结果是一行(可以是多列),这种子查询称为行子查询。

常用的操作符:=,<>,IN,NOT IN。

例子:

--查询与“林炜翔”性别相同,地址相同的员工信息
--a.查询林炜翔的性别和地址
mysql> select gender, addr from emp where name = '林炜翔';
+--------+------+
| gender | addr |
+--------+------+
| 男     | 上海 |
+--------+------+
--b.查询与“林炜翔”性别相同,地址相同的员工信息
mysql> select * from emp where (gender, addr) = (select gender, addr from emp where name = '林炜翔');
+------+------------+--------+--------+------+--------------+------------+------+--------+---------+
| id   | employeeId | name   | gender | age  | idCardNumber | hireDate   | addr | salary | club_id |
+------+------------+--------+--------+------+--------------+------------+------+--------+---------+
|    1 | LWX        | 林炜翔 | 男     |   22 | 888          | 2020-11-22 | 上海 |  12000 |       4 |
|    1 | Crisp      | 刘青松 | 男     |   26 | 777          | 2020-11-22 | 上海 |  11000 |       3 |
|    1 | Doinb      | 金泰相 | 男     |   26 | 012          | 2020-11-22 | 上海 |  14000 |       5 |
|    1 | Tian       | 小天   | 男     |   24 | 013          | 2020-11-22 | 上海 |  12520 |       6 |
+------+------------+--------+--------+------+--------------+------------+------+--------+---------+
表子查询

子查询返回的结果是多行多列,这种子查询称为表子查询。

例子:

--查询与小黄人或者简自豪的性别和地址相同的员工信息
--a.查询小黄人或者简自豪的性别和地址
mysql> select gender, addr from emp where name = '小黄人' or name = '简自豪';
+--------+------+
| gender | addr |
+--------+------+
| 男     | 湖北 |
| 男     | 广西 |
+--------+------+
--b.查询与小黄人或者简自豪的性别和地址相同的员工信息
mysql> select * from emp where (gender, addr) in (select gender, addr from emp where name = '小黄人' or name = '简自豪');
+------+--------------+--------+--------+------+--------------+------------+------+--------+---------+
| id   | employeeId   | name   | gender | age  | idCardNumber | hireDate   | addr | salary | club_id |
+------+--------------+--------+--------+------+--------------+------------+------+--------+---------+
|    4 | UZI          | 简自豪 | 男     |   26 | 006          | 2023-08-18 | 湖北 |   9800 |       2 |
|    7 | xiaohuangren | 小黄人 | 男     |   18 | 999          | 2023-08-25 | 广西 |   8000 |    NULL |
|    8 | angel        | 向涛   | 男     |   22 | 676          | 2018-07-07 | 广西 |  11000 |       3 |
+------+--------------+--------+--------+------+--------------+------------+------+--------+---------+


--查询入职日期在20201122之后入职的员工信息以及部门名称
--a.查询入职日期在20201122之后入职的员工信息
select * from emp where hiredate > '20201122';
--b.查询入职日期在20201122之后入职的员工信息以及部门名称
mysql> select * from (select * from emp where hiredate > '20201122') e left join club on e.club_id = club.id;
+------+--------------+--------+--------+------+--------------+------------+------+--------+---------+------+------+
| id   | employeeId   | name   | gender | age  | idCardNumber | hireDate   | addr | salary | club_id | id   | name |
+------+--------------+--------+--------+------+--------------+------------+------+--------+---------+------+------+
|    3 | 369          | 白家浩 | 男     |   25 | 008          | 2022-02-28 | 湖南 |  13800 |       1 |    1 | JDG  |
|    4 | UZI          | 简自豪 | 男     |   26 | 006          | 2023-08-18 | 湖北 |   9800 |       2 |    2 | EDG  |
|    6 | Karsa        | 卡萨   | 女     |   18 | 818          | 2023-08-18 | 上海 |   9800 |       3 |    3 | WBG  |
|    7 | xiaohuangren | 小黄人 | 男     |   18 | 999          | 2023-08-25 | 广西 |   8000 |    NULL | NULL | NULL |
+------+--------------+--------+--------+------+--------------+------------+------+--------+---------+------+------+

多表查询例子
--查询所有学生的选课情况,展示学生姓名,学号,课程名称
--涉及到三张表,学生表,课程表,以及学生-课程关系表
mysql> select stu.name, stu.no,cour.name from stu,stu_cour,cour 
where stu.id = stu_cour.stu_id and stu_cour.cour_id = cour.id;
+------+------+--------+
| name | no   | name   |
+------+------+--------+
| 肥春 | 001  | java   |
| 肥春 | 001  | c++    |
| 肥波 | 002  | c++    |
| 肥春 | 001  | python |
| 肥波 | 002  | python |
| 肥龙 | 003  | php    |
+------+------+--------+

事务

事务简介

事务是一组操作的集合,要么同时成功,要么同时失败。

事务操作

查看/设置事务提交方式

SELECT @@autocommit; --查看
SET @@autocommit = 0; --设置

开启事务

START TRANSACTION 或 BEGIN;

提交事务

COMMIT;

回滚事务

ROLLBACK;
事务四大特性(ACID)

1.原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。

2.一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。

3.隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。

4.持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

并发事务问题
问题描述
脏读一个事务读到另一个事务还没有提交的数据。
不可重复读一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。
幻读一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了“幻影”。

事务隔离级别
隔离级别脏读不可重复度幻读
read uncommited
read committed×
repeatable read(默认)××
serializable×××

.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值