山东网站建设谷歌关键词排名查询
基本SQL语句分类
DDL(数据定义语言)
数据定义语言,用来定义数据库对象(数据库、表、字段)。
数据控制语言,用来创建数据库用户、控制数据库的控制权限。
数据库操作
查询所有数据库:
SHOW DATABASES;
查询当前数据库:
SELECT DATABASE();
创建数据库:
CREATE DATABASE [ IF NOT EXISTS ] 数据库名 [ DEFAULT CHARSET 字符集] [COLLATE 排序规则 ];
删除数据库:
DROP DATABASE [ IF EXISTS ] 数据库名;
使用数据库:
USE 数据库名;
注意事项
• UTF8字符集长度为3字节,有些符号占4字节,所以推荐用utf8mb4字符集
创建表:
CREATE TABLE 表名(字段1 字段1类型 [COMMENT 字段1注释],字段2 字段2类型 [COMMENT 字段2注释],字段3 字段3类型 [COMMENT 字段3注释],...字段n 字段n类型 [COMMENT 字段n注释]
)[ COMMENT 表注释 ];
添加字段:ALTER TABLE 表名 ADD 字段名 类型(长度) [COMMENT 注释] [约束];
例:ALTER TABLE emp ADD nickname varchar(20) COMMENT '昵称';
修改数据类型:ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度);
修改字段名和字段类型:ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [COMMENT 注释] [约束];
例:将emp表的nickname字段修改为username,类型为varchar(30)ALTER TABLE emp CHANGE nickname username varchar(30) COMMENT '昵称';
删除字段:ALTER TABLE 表名 DROP 字段名;
修改表名:ALTER TABLE 表名 RENAME TO 新表名
删除表:DROP TABLE [IF EXISTS] 表名;
删除表,并重新创建该表:TRUNCATE TABLE 表名;
DML(数据操作语言)
数据操作语言,用来对数据库表中的数据进行增删改操作。
添加数据
指定字段:INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...);
全部字段:INSERT INTO 表名 VALUES (值1, 值2, ...);
批量添加数据:INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...);
INSERT INTO 表名 VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...);
注意事项
- 字符串和日期类型数据应该包含在引号中
- 插入的数据大小应该在字段的规定范围内
更新和删除数据
修改数据:UPDATE 表名 SET 字段名1 = 值1, 字段名2 = 值2, ... [ WHERE 条件 ];
例:UPDATE emp SET name = 'Jack' WHERE id = 1;
删除数据:DELETE FROM 表名 [ WHERE 条件 ];
DQL(数据查询语言)
数据查询语言,用来查询数据库中表的记录(常用)。
查询语句是MySQL中最常用的语句,因此需要重点掌握,大致语法可以写成这样:
SELECT字段列表
FROM表名字段
WHERE条件列表
GROUP BY分组字段列表
HAVING分组后的条件列表
ORDER BY排序字段列表
LIMIT分页参数
例如,我们构建下面这张表:
create table emp(id int comment '编号',workno varchar(10) comment '工号',name varchar(10) comment '姓名',gender char(1) comment '性别',age tinyint unsigned comment '年龄',idcard varchar(18) comment '身份证号',workaddress varchar(50) comment '工作地址',entrydate date comment '入职时间'
)comment '员工表';
基本查询:
查询多个字段:SELECT 字段1, 字段2, 字段3, ... FROM 表名;
SELECT * FROM 表名;
设置别名:SELECT 字段1 [ AS 别名1 ], 字段2 [ AS 别名2 ], 字段3 [ AS 别名3 ], ... FROM 表名;
SELECT 字段1 [ 别名1 ], 字段2 [ 别名2 ], 字段3 [ 别名3 ], ... FROM 表名;
去除重复记录:SELECT DISTINCT 字段列表 FROM 表名;
转义:SELECT * FROM 表名 WHERE name LIKE '/_张三' ESCAPE '/'
/ 之后的_不作为通配符
1.查询指定字段 name,workno,age 返回 select name,workno,age from emp;2.查询所有字段返回 select id, workno, name, gender, age, idcard, workaddress, entrydate from emp;select * from emp; -- 虽然简洁,但是尽量不要写,因为不直观,而且效率低3.查询所有员工的工作地址,起别名 select workaddress as '工作地址' from emp;select workaddress '工作地址' from emp; 4.查询公司员工的上班地址(不要重复) select distinct workaddress '工作地址' from emp;
条件查询:
条件:
比较运算符 | 功能 |
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
= | 等于 |
<>或!= | 不等于 |
between...and | 在某个范围内(含最小、最大值) |
in(...) | 在in之后的列表中的值,多选一 |
like占位符 | 模糊匹配(_匹配单个字符,%匹配任意个字符) |
is null | 是null |
逻辑运算符 | 功能 |
and或&& | 且(所有条件同时成立) |
or或|| | 或(任意一个条件成立) |
not或! | 非(不是) |
例:
-- 1.查询年龄等于88的员工
select * from emp where age = 88;
-- 2.查询年龄小于20的员工信息
select * from emp where age <20;
-- 3. 查询年龄小于等于20的员工信息
select * from emp where age <=20;
-- 4.查询没有身份证号的员工信息
select * from emp where !idcard ;select * from emp where idcard is null ;-- 5.查询有身份证号的员工信息select * from emp where idcard ;select * from emp where idcard is not null ;-- 6.查询年龄不等于88的员工信息select * from emp where age != 88;select * from emp where age <> 88;-- 7.查询年龄在15岁(包含)到20岁(包含)之间的员工信息select * from emp where age>=15 && age <=20;select * from emp where age>=15 and age <=20;select * from emp where age between 15 and 20;-- 8.查询性别为 女 且年龄小于25岁的员工信息select * from emp where gender = '女' && age < 25;select * from emp where gender = '女' and age < 25;-- 9.查询年龄等于18或20或40的员工信息select * from emp where age = 18 || age = 20 || age = 40;select * from emp where age = 18 or age = 20 or age = 40;select * from emp where age in(18,20,40);-- 10.查询姓名为两个字的员工信息 like(模糊匹配,_ 表示单个字符 % 表示任意字符)
select * from emp where name like '__' ;-- 11.查询身份证号最后一位是X的员工信息
select * from emp where idcard like '%X';
select * from emp where idcard like '_________________X';
聚合函数
常见的聚合函数:
函数 | 功能 |
count | 统计数量 |
max | 最大值 |
min | 最小值 |
avg | 平均数 |
sum | 求和 |
语法:
SELECT 聚合函数(字段列表) FROM 表名;
例:
-- 1.统计该企业员工数量
select count(*) from emp;
select count(id) from emp;-- 2.统计该企业员工的平均年龄
select avg(age) from emp;-- 3.统计该企业员工的最大年龄
select max(age) from emp;-- 4.统计该企业员工的最小年龄
select min(age) from emp;-- 5.统计西安地区员工的年龄之和
select sum(age) from emp;
分组查询
语法:SELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 分组字段名 [ HAVING 分组后的过滤条件 ];
where 和 having 的区别:
• 执行时机不同:where是分组之前进行过滤,不满足where条件不参与分组;having是分组后对结果进行过滤。
• 判断条件不同:where不能对聚合函数进行判断,而having可以。
例:
-- 1.根据性别分组,统计男性员工和女性员工的数量
select gender,count(*) from emp group by gender ;-- 2.根据性别分组,统计男性员工和女性员工的平均年龄select gender,avg(age) from emp group by gender ;-- 3.查询年龄小于45的员工,并根据工作地址分组,获取员工数量大于等于3的工作地址
select workaddress,count(*) from emp where age< 45 group by workaddress having count(*)>=3;-- 排序查询
-- 语法: select 字段列表 from 表名 order by 字段1 排序方式1 , 字段2 排序方式2;-- 1.根据年龄对公司的员工进行升序排序
select * from emp order by age asc;
select * from emp order by age desc ; -- 降序排序
select * from emp order by age; -- 默认是升序-- 2.根据入职时间,对员工进行降序排序
select * from emp order by entrydate desc;-- 3.根据年龄对公司的员工进行升序排序,年龄相同,再按照入职时间进行降序排序
select * from emp order by age asc , entrydate desc;
排序查询
语法:SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1, 字段2 排序方式2;
排序方式:
- ASC: 升序(默认)
- DESC: 降序
例:
-- 1.根据年龄对公司的员工进行升序排序
select * from emp order by age asc;
select * from emp order by age desc ; -- 降序排序
select * from emp order by age; -- 默认是升序-- 2.根据入职时间,对员工进行降序排序
select * from emp order by entrydate desc;-- 3.根据年龄对公司的员工进行升序排序,年龄相同,再按照入职时间进行降序排序
select * from emp order by age asc , entrydate desc;
分页查询
语法: select 字段列表 from 表名 limit 起始索引,查询记录数;
注:起始索引从0开始,起始索引 = (查询页码 - 1)* 每页显示记录数 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL中是limit 如果查询的是第一页的数据,起始索引可以省略,直接简写为 limit 10。
例:
select * from emp limit 0,10;select * from emp limit 10;
-- 2.查询第2页员工数据,每页展示10条记录 (每页 = (页码-1)*展示记录数)
select * from emp limit 10,10;
DCL
DCL一般用于管理用户权限相关操作,常用的有如下:
-- 创建用户 itcast,只能够在当前主机localhost访问,密码123456;create user 'itcast'@'localhost' identified by '123456';-- 创建用户 heima ,可以在任意主机访问该数据库,密码123456;
create user 'heima'@'%' identified by '123456';-- 修改用户 heima 的访问密码为 1234;
alter user 'heima'@'%' identified by '1234';-- 删除itcast@localhost用户
drop user 'itcast'@'localhost';-- DCL-权限控制
-- 1.查询权限
show grants for 'heima'@'%';-- 2.授予权限
grant all on emp.* to 'heima'@'%';-- 3.撤销权限
revoke all on emp.* from 'heima'@'%';
注:主机名可以使用%通配。
多个权限用逗号分隔
授权时,数据库名和表名可以用 * 进行通配,代表所有。
函数
函数 | 功能 |
---|---|
CONCAT(s1, s2, …, sn) | 字符串拼接,将s1, s2, …, sn拼接成一个字符串 |
LOWER(str) | 将字符串全部转为小写 |
LPAD(str, n, pad) | 左填充,用字符串pad对str的左边进行填充,达到n个字符串长度 |
RPAD(str, n, pad) | 右填充,用字符串pad对str的右边进行填充,达到n个字符串长度 |
TRIM(str) | 去掉字符串头部和尾部的空格 |
SUBSTRING(str, start, len) | 返回从字符串str从start位置起的len个长度的字符串 |
CEIL(x) | 向上取整 |
FLOOR(x) | 向下取整 |
MOD(x, y) | 返回x/y的模 |
RAND() | 返回0~1内的随机数 |
ROUND(x, y) | 求参数x的四舍五入值,保留y位小数 |
CURDATE() | 返回当前日期 |
CURTIME() | 返回当前时间 |
NOW() | 返回当前日期和时间 |
YEAR(date) | 获取指定date的年份 |
MONTH(date) | 获取指定date的月份 |
DAY(date) | 获取指定date的日期 |
DATE_ADD(date, INTERVAL expr type) | 返回一个日期/时间值加上一个时间间隔expr后的时间值 |
DATEDIFF(date1, date2) | 返回起始时间date1和结束时间date2之间的天数 |
-- 常用函数
-- lower 将字符串转成小写
select lower('Hello');-- uper 将字符串转成大写
select upper('Hello');-- lpad 左侧填充
select lpad('01',5,'-');
-- rpad 右侧填充
select rpad('01',5,'-');-- trim 去除首尾的空格,中间的不去除
select trim(' Hello MySQL ');-- substring
select substring('Hello MySQL',1,5);-- 1.将员工工号变为统一的五位数,不足的在前面补0
update emp set workno = lpad(workno,5,'0');-- 数值函数
-- ceil 向上取整
select ceil(1.5);
-- floor 向下取整
select floor(1.1);
-- mod 求模运算
select mod(5,4);
-- ran 0-1之间的随机数
select rand();
-- round 对...进行四舍五入,保留...位小数
select round(2.345,2);-- 案例:通过数据库的函数,生成一个六位数的随机验证码
select lpad(round(rand()*1000000,0),6,0);-- 日期函数
-- curdate() 当前日期
select curdate();-- curtime() 当前是几点
select curtime();-- now() 当前的年月日时分秒
select now();-- year,month,day
select year(now());select month(now());select day(now());-- date add 从什么时候开始,往前/后推多少时间
select date_add(now(),interval 70 day );-- datediff 两个时间之间相差多少天
select datediff('2024-8-17','2005-05-08');-- 案例:查询所有员工的入职天数,并根据入职天数倒序排序
select name,datediff(curdate(),entrydate) as 'entrydays' from emp order by 'entrydays' desc;-- 流程控制函数-- if 存在,返回第一个,不存在,返回第二个
select if(true,'OK','ERROR');-- ifnull 一个个值不为null,返回第一个,否则返回第二个select ifnull(null,'Defult');-- case when then else end-- 需求:查询emp表的员工姓名和工作地址(如果是北京/上海 返回一线城市 否则返回二线城市)select name,(case workaddress when '北京' then '一线城市' when '上海' then '一线城市' else '二线城市' end) as '工作地址'from emp;-- 案例:统计班级各个学员的成绩,展示规则如下:
-- >= 85展示优秀
-- >= 60展示及格
-- 否则展示不及格
create table score(id int comment 'ID',name varchar(20) comment '姓名',math int comment '数学',english int comment '英语',chinese int comment '语文'
) comment '学员成绩表';
insert into score(id,name,math,english,chinese) values (1,'Tom',67,88,95),(2,'Rose',23,66,90),(3,'Jack',56,98,76);selectid,name,(case when math >=85 then '优秀' when math >=60 then '及格' else '不及格' end) '数学',(case when english >=85 then '优秀' when english >=60 then '及格' else '不及格' end) '英语' ,(case when chinese >=85 then '优秀' when chinese >=60 then '及格' else '不及格' end) '语文'from score;
约束
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制该字段的数据不能为null | NOT NULL |
唯一约束 | 保证该字段的所有数据都是唯一、不重复的 | UNIQUE |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | PRIMARY KEY |
默认约束 | 保存数据时,如果未指定该字段的值,则采用默认值 | DEFAULT |
检查约束(8.0.1版本后) | 保证字段值满足某一个条件 | CHECK |
外键约束 | 用来让两张图的数据之间建立连接,保证数据的一致性和完整性 | FOREIGN KEY |
例:
create table user(id int primary key auto_increment comment '主键', -- primary key 主键,auto_increment自动增长name varchar(10) not null unique comment '姓名',-- not null 不为空 , unique唯一age int check ( age > 0 && age <= 120) comment '年龄', -- check 检查约束,后面跟条件status char(1) default '1' comment '状态', -- default 默认 后面跟默认的值gender char(1) comment '性别'
)comment '用户表';-- 插入数据
insert into user(name, age, status, gender) values ('张三',18,1,'男'),('李四',19,0,'女');-- 无法执行,违反name字段 not null 约束
insert into user(name, age, status, gender) values (null,18,1,'男');
-- 无法执行,违反了name字段的unique(唯一)约束
insert into user(name, age, status, gender) values ('张三',18,1,'男');-- 插入,违反check检查字段
insert into user(name, age, status, gender) values ('王五',-1,1,'男');
insert into user(name, age, status, gender) values ('王五',121,1,'男');
-- 可以执行,status默认为1 这里会发现主键多增长了几个,原因是因为前面的语句虽然插入失败,但是系统为他们执行的时候自增长了主键
insert into user(name, age, gender) values ('王五',21,'男');
外键约束:
当两张表需要关联的时候,就需要用到外键约束。
例:
-- ================约束(外键)==================
-- 准备数据
create table dept(id int auto_increment comment 'ID' primary key ,name varchar(50) not null comment '部门名称'
)comment '部门表';
insert into dept (id, name)
values (1,'研发部'),(2,'市场部'),(3,'财务部'),(4,'销售部'),(5,'总经办');create table emp(id int auto_increment comment 'ID' primary key ,name varchar(50) not null comment '姓名',age int comment '年龄',job varchar(20) comment '职位',salary int comment '薪资',entrydate date comment '入职时间',management int comment '直属领导ID',dept_id int comment '部门ID'
)comment '员工表';INSERT INTO emp (name, age, job, salary, entrydate, management, dept_id) VALUES
('李明', 28, '开发工程师', 8000, '2023-01-15', NULL, 1),
('张辉', 35, '项目经理', 12000, '2022-05-01', 1, 1),
('王芳', 30, '测试工程师', 7000, '2023-03-10', 2, 1),
('赵强', 40, '产品经理', 15000, '2021-08-12', NULL, 2),
('刘伟', 25, '运维专员', 6000, '2023-10-01', 1, 3);-- 添加外键
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);-- 删除外键
alter table emp drop foreign key fk_emp_dept_id;-- 外键的删除和更新行为 cascade 极连
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id) on update cascade on DELETE cascade ;-- 如果增加或删除父表的外键值,则将子表中的设置为null(前提是可以为nullm否则该语句直接不允许执行)
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id) on update set null on DELETE set null ;
多表查询
多表关系
- 一对多(多对一)
- 多对多
- 一对一
一对多
案例:部门与员工
关系:一个部门对应多个员工,一个员工对应一个部门
实现:在多的一方建立外键,指向一的一方的主键
多对多
案例:学生与课程
关系:一个学生可以选多门课程,一门课程也可以供多个学生选修
实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
一对一
案例:用户与用户详情
关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率
实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)
查询
合并查询(笛卡尔积,会展示所有组合结果):select * from employee, dept;
笛卡尔积:两个集合A集合和B集合的所有组合情况(在多表查询时,需要消除无效的笛卡尔积)
消除无效笛卡尔积:select * from employee, dept where employee.dept = dept.id;
内连接查询
内连接查询的是两张表交集的部分
隐式内连接:SELECT 字段列表 FROM 表1, 表2 WHERE 条件 ...;
显式内连接:SELECT 字段列表 FROM 表1 [ INNER ] JOIN 表2 ON 连接条件 ...;
显式性能比隐式高
例:
-- 多表查询 出现笛卡尔积现象
select * from emp , dept;
-- 消除笛卡尔积现象
select * from emp , dept where emp.id = dept.id;-- 内连接
-- 1.查询每个员工的姓名,及相关部门的名称(隐式内连接)
-- 表结构:emp,dept
-- 连接条件: emp.dept_id = dept.id
select emp.name,dept.name from emp,dept where emp.id = dept.id;-- 起了别名之后,就不能用原表名了,否则报错
select e.name ,d.name from emp e,dept d where e.id = d.id;-- 2. 查询每一个员工的姓名,及关联部门的名称(显式内连接) --- inner join ... on ...
select e.name,d.name from emp e inner join dept d on e.id = d.id;
-- inner 可以去掉
select e.name,d.name from emp e join dept d on e.id = d.id;
外连接查询
左外连接:
查询左表所有数据,以及两张表交集部分数据SELECT 字段列表 FROM 表1 LEFT [ OUTER ] JOIN 表2 ON 条件 ...;
相当于查询表1的所有数据,包含表1和表2交集部分数据
右外连接:
查询右表所有数据,以及两张表交集部分数据SELECT 字段列表 FROM 表1 RIGHT [ OUTER ] JOIN 表2 ON 条件 ...;
例:
-- 外连接
-- 1.查询emp表的所有数据,和对应的部门信息(左外连接)
-- 表结构:emp,dept
-- 连接条件:emp.dept_id = dept.id-- 左外连接
select e.* , d.name from emp e left outer join dept d on e.dept_id = d.id;
-- outer可省略
select e.* , d.name from emp e left join dept d on e.dept_id = d.id;-- 右外连接
select d.* , e.* from emp e right join dept d on e.dept_id = d.id;
值得注意的是,我们也可以将右外连接转换为左外连接,因此在实际使用中,我们一般用左外连接。
自连接查询
当前表与自身的连接查询,自连接必须使用表别名
语法:SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件 ...;
自连接查询,就是将表中的某个元素当成是另一个表进行查询。
例:
-- 自连接
-- 1.查询员工 及其所属领导的名字
-- 表结构 emp-- 必须起别名,否则无法执行
-- 没有领导的不会显示
select * from emp a , emp b where a.management = b.id;-- 显示emp所有员工和领导,即使没有直属领导也要显示
select a.name '员工',b.name '领导' from emp a left join emp b on a.management = b.id;
联合查询 union, union all
把多次查询的结果合并,形成一个新的查询集
语法:
SELECT 字段列表 FROM 表A ...
UNION [ALL]
SELECT 字段列表 FROM 表B ...
注意事项
- UNION ALL 会有重复结果,UNION 不会
- 联合查询比使用or效率高,不会使索引失效
例:
-- 联合查询
-- union all ,union
-- 1.将薪资低于8000的员工和年龄大于30岁的员工全部查询出来
use itheima;
select * from emp where itheima.emp.salary <8000union all
select * from emp where age > 30;-- all 删除后 去重
select * from emp where itheima.emp.salary <8000union
select * from emp where age > 30;
子查询
SQL语句中嵌套SELECT语句,称谓嵌套查询,又称子查询。SELECT * FROM t1 WHERE column1 = ( SELECT column1 FROM t2);
子查询外部的语句可以是 INSERT / UPDATE / DELETE / SELECT 的任何一个
根据子查询结果可以分为:
- 标量子查询(子查询结果为单个值)
- 列子查询(子查询结果为一列)
- 行子查询(子查询结果为一行)
- 表子查询(子查询结果为多行多列)
根据子查询位置可分为:
- WHERE 之后
- FROM 之后
- SELECT 之后
标量子查询
子查询返回的结果是单个值(数字、字符串、日期等)。
常用操作符:- < > > >= < <=
例:
-- 标量子查询
-- 1.查询"销售部"的所有员工信息
-- a.查询出销售部的部门idselect id from dept where name = '销售部';
-- b.根据销售部部门ID,查询员工信息select * from emp where id = 4;select * from emp where id = (select id from dept where name = '销售部');-- 2.查询张辉入职之后的员工信息-- a.查询 张辉 的入职日期
select entrydate from emp where name = '张辉';
-- b.查询指定日期之后入职的员工信息
select * from emp where entrydate > '2022-05-01';select * from emp where emp.entrydate > (select entrydate from emp where name = '张辉');
列子查询
返回的结果是一列(可以是多行)。
常用操作符:
操作符 | 描述 |
---|---|
IN | 在指定的集合范围内,多选一 |
NOT IN | 不在指定的集合范围内 |
ANY | 子查询返回列表中,有任意一个满足即可 |
SOME | 与ANY等同,使用SOME的地方都可以使用ANY |
ALL | 子查询返回列表的所有值都必须满足 |
例:
-- 列子查询
-- 1.查询“销售部”和“市场部”的所有员工信息
-- a.查询“销售部”和“市场部”的ID
select id from dept where name = '销售部' or name = '市场部';
-- b.查询指定ID下的所有员工信息
select * from emp where id in (2,4);select * from emp where id in (select dept.id from dept where name = '销售部' or name = '市场部');-- 2.查询比财务部所有人工资都高的员工信息
-- a.查询所有财务部人员工资
select id from dept where name = '财务部';select itheima.emp.salary from emp where id = 3;select itheima.emp.salary from emp where id = (select id from dept where name = '财务部');
-- b.查询所有比财务部薪资高的人员
select * from emp where itheima.emp.salary > all (select itheima.emp.salary from emp where id = (select id from dept where name = '财务部'));
-- 查询比研发部其中任意一人工资高的员工信息
-- a.查询研发部所有员工工资
select itheima.emp.salary where itheima.emp.id = (select id from dept where name = '研发部');
-- b.比研发部其中任意一人工资高的员工信息
select * from emp where itheima.emp.salary > any (select itheima.emp.salary where itheima.emp.id = (select id from dept where name = '研发部'));
行子查询
返回的结果是一行(可以是多列)。
常用操作符:=, <, >, IN, NOT IN
例:
-- 行子查询
-- 1.查询“刘伟”的薪资及直属领导相同的员工信息
-- a.查询“刘伟”的薪资及直属领导
select itheima.emp.salary , itheima.emp.management from emp where name = '刘伟';
-- b.查询和“刘伟”薪资和直属领导相同的员工信息
select * from emp where (select itheima.emp.salary , itheima.emp.management from emp where name = '刘伟');
表子查询
返回的结果是多行多列
常用操作符:IN
例:
-- 表子查询
-- 1.查询“李明”,“张翰”的职位和薪资相同的员工
-- a.查询“李明”,“张翰”的职位和薪资
select itheima.emp.salary,itheima.emp.job from emp where name = '李明' or name = '张翰';
-- b.查询“李明”,“张翰”的职位和薪资相同的员工
select * from itheima.emp where (salary,job) in (select itheima.emp.salary,itheima.emp.job from emp where name = '李明' or name = '张翰');
-- 2.查询入职日期是“2021-08-12”之后的员工信息,及其部门信息
-- a.入职日期是“2021-08-12”之后的员工信息
select * from emp where entrydate > '2021-08-12';
-- b.查询这部分员工,对应的部门信息
select e.*,d.* from (select * from emp where entrydate > '2021-08-12') e left join dept d on itheima.emp.dept_id = d.id;
事务
事务是一组操作的集合,事务会把所有操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
例:
-- 转账操作
-- 1.查询张三账户的余额select * from account where name = '张三';-- 2.将张三账户的余额 -1000update account set money = money - 1000 where name = '张三';-- 如果在这中间出现了异常,那么就会导致张三的钱少了1000,但是李四的钱病没有多1000-- 3.将李四账户的余额+1000update account set money = money + 1000 where name = '李四';
此时为了避免,我们可以将事务改为手动提交
方式一
-- 方式一
select @@autocommit;set @@autocommit = 0; -- 设置为手动提交-- 转账操作
-- 1.查询张三账户的余额select * from account where name = '张三';-- 2.将张三账户的余额 -1000update account set money = money - 1000 where name = '张三';-- 如果在这中间出现了异常,那么就会导致张三的钱少了1000,但是李四的钱病没有多1000
-- 因为每一条SQL语句都能被看做是一条事务,因此为了避免该情况,我们可以将事务调整为手动提交-- 3.将李四账户的余额+1000update account set money = money + 1000 where name = '李四';-- 提交事务
commit ;-- 回滚事务
rollback ;
方式二
-- 方式二
start transaction ;
-- 转账操作
-- 1.查询张三账户的余额select * from account where name = '张三';-- 2.将张三账户的余额 -1000update account set money = money - 1000 where name = '张三';-- 如果在这中间出现了异常,那么就会导致张三的钱少了1000,但是李四的钱病没有多1000-- 3.将李四账户的余额+1000update account set money = money + 1000 where name = '李四';-- 提交事务
commit ;-- 回滚事务 一旦执行过程中出错,执行该任务
rollback ;
以上就是MySQL基础篇中的全部内容。