目录
查询数据库表中数据
where 条件列表
group by 分组查询
having 分组后条件列表
order by 排序字段列表
limit 分页参数
多表设计
一对多
多对多
一对一
多表查询
事物
索引
关键字:SELECT
中间有空格,加引号
select 字段列表
查询多个字段:select 字段1, 字段2, 字段3 from 表名;
查询所有字段(通配符):select * from 表名;
设置别名:select 字段1 [ as 别名1 ] , 字段2 [ as 别名2 ] from 表名;
去除重复记录:select distinct 字段列表 from 表名;
from 表名列表
条件查询:select 字段列表 from 表名 where 条件列表 ;
比较运算符 |
功能 |
> |
大于 |
>= |
大于等于 |
< |
小于 |
<= |
小于等于 |
= |
等于 |
<> 或 != |
不等于 |
between ... and ... |
在某个范围之内(含最小、最大值) |
in(...) |
在in之后的列表中的值,多选一 |
like 占位符 |
模糊匹配( _匹配单个字符, %匹配任意个字符) |
is null |
是null |
逻辑运算符 |
功能 |
and 或 && |
并且 (多个条件同时成立) |
or 或 || |
或者 (多个条件任意一个成立) |
not 或 ! |
非 , 不是 |
-- 1. 查询 姓名 为 杨逍 的员工
select * from emp where name = '杨逍';-- 2. 查询在 id小于等于5 的员工信息
select * from emp where id <= 5;-- 3. 查询 没有分配职位 的员工信息 -- 判断 null , 用 is null
select * from emp where job is null;-- 4. 查询 有职位 的员工信息 -- 判断 不是null , 用 is not null
select * from emp where job is not null ;-- 5. 查询 密码不等于 '123456' 的员工信息
select * from emp where password != '123456';-- 6. 查询入职日期 在 '2000-01-01' (包含) 到 '2010-01-01'(包含) 之间的员工信息
select * from emp where entrydate between '2000-01-01' and '2010-01-01' ;-- 7. 查询 入职时间 在 '2000-01-01' (包含) 到 '2010-01-01'(包含) 之间 且 性别为女 的员工信息
select * from emp where (entrydate between '2000-01-01' and '2010-01-01') and gender = 2;-- 8. 查询 职位是 2 (讲师), 3 (学工主管), 4 (教研主管) 的员工信息
select * from emp where job = 2 or job = 3 or job = 4;select * from emp where job in (2,3,4);
-- 9. 查询姓名为两个字的员工信息
select * from emp where name like '__';-- 10. 查询姓 '张' 的员工信息 ---------> 张%
select * from emp where name like '张%';-- 11. 查询姓名中包含 '三' 的员工信息
select * from emp where name like '%三%';
聚合函数
定义:将一列数据作为一个整体,进行纵向计算。
语法:select 聚合函数(字段列表) from 表名 ;
函数 |
功能 |
count |
统计数量 |
max |
最大值 |
min |
最小值 |
avg |
平均值 |
sum |
求和 |
null值不参与所有聚合函数运算。
统计数量可以使用:count(*) count(字段) count(常量),推荐使用count(*)。
-- 聚合函数
-- 1. 统计该企业员工数量 -- count
-- A. count(字段)
select count(id) from emp;
select count(job) from emp; -- null值不参与聚合函数运算-- B. count(*)
select count(*) from emp;-- C. count(值)
select count(1) from emp;-- 2. 统计该企业员工 ID 的平均值
select avg(id) from emp;-- 3. 统计该企业最早入职的员工的入职日期
select min(entrydate) from emp;-- 4. 统计该企业最近入职的员工的入职日期
select max(entrydate) from emp;-- 5. 统计该企业员工的 ID 之和
select sum(id) from emp;
分组查询:select 字段列表 from 表名 [ where 条件 ] group by 分组字段名 [ having 分组后过滤条件 ];
-- 1. 根据性别分组 , 统计男性和女性员工的数量 -- count(*)
select gender , count(*) from emp group by gender;-- 2. 先查询入职时间在 '2015-01-01' (包含) 以前的员工 , 并对结果根据职位分组 , 获取员工数量大于等于2的职位 -- count
select job ,count(*) from emp where entrydate <= '2015-01-01' group by job having count(*) >= 2;
here与having区别
1.执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组之后对结果进行过滤。
2.判断条件不同:where不能对聚合函数进行判断,而having可以。
注意:分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义。
执行顺序: where > 聚合函数 > having 。
条件查询:select 字段列表 from 表名 [ where 条件列表 ] [ group by 分组字段 ] order by 字段1 排序方式1 , 字段2 排序方式2;
ASC:升序(默认值)
DESC:降序
如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序。
-- 1. 根据入职时间, 对员工进行升序排序 -- 排序条件
select * from emp order by entrydate asc ; -- 默认升序, asc可以省略的-- 2. 根据 入职时间 对公司的员工进行 升序排序 , 入职时间相同 , 再按照 ID 进行降序排序
select * from emp order by entrydate asc , id desc ;
分页查询:select 字段列表 from 表名 limit 起始索引, 查询记录数 ;
-- 1. 查询第1页员工数据, 每页展示10条记录
select * from emp limit 0,10;select * from emp limit 10;
-- 2. 查询第2页员工数据, 每页展示10条记录
select * from emp limit 10,10;-- 公式 : 页码 ---> 起始索引 -------> 起始索引 = (页码 - 1) * 每页记录数
案例:select *from emp where name like '%张' and gender = 1 and entrydate between '2000-01-01' and '2015-12-31' order by update_time desc limt 10 ;
一对多关系实现:在数据库表中多的一方,添加字段,来关联一的一方的主键。
(父表)部门及员工(子表)模块的表结构
create table tb_dept(
id int unsigncd primary kcy auto increment commont '上键ID',
name varchar(10) not null unique comment '部门名称',
create_time datetime not null comment '创建时间',
update_time datetime not null commenl '修改时间'
comment '部门表';
dept_id int unsigned comment '归属的部门 ID';
create table tb_emp(
id int unsigned primary key auto_increment comment 'ID',
username varchar(20) not null unique comment '用户名',
password varchar(32) default '123456 comment '密码',
name varchar(10) not null comment '姓名',
gender tinyint unsigned not null comment "性别,说明:1 男,2 女',
image varchar(300) comment '图像',
job tinyint unsigned comment '职位,说明:1 班主任,2 讲师,3 学工主管,4 教研主管',
entrydate date comment '入职时间',dept_id int unsigned comment '归属的部门ID';
create time datetime not null comment '创建时间,
update time datetime not null comment '修改时间'
) comment '员工表';
在数据库层面,并未建立关联,所以是无法保证数据的一致性和完整性的
外键约束
-- 1.创建表时指定
create table 表名(
字段名 数据类型,
...
[constraint] [外键名称] foreign key (外键字段名) references 主表/父表 (字段名)
);
-- 2.建完表后,添加外键
alter table 表名 add constraint 外键名称 foreign key (外键字段名) references 主表(字段名);
概念:在业务层逻辑中,解决外键关联。
通过逻辑外键,就可以很方便的解决上述问题。
案例: 学生 与 课程的关系
关系: 一个学生可以选修多门课程,一门课程也可以供多个学生选择
实现:建立第三张中间表,中间表至少包含两个外键,分别
案例: 用户 与 身份证信息 的关系
关系: 一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他字段放在另一张表中,以提升操作效率
实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)
constraint fk_user_id foreign key (user_id) references tb_user(id)
案例
主键:int unsigned 无符号int
tinyint unsigned 排序(0-99数字)
varchar(20) 长度不固定 变相说明不能为空
decimal(8,2) 总长8,2位的小数
图片 varchar(300)
select * from tb_emp,tb_dept;
笛卡尔积,在数学中,两个集合的所用组合情况
select * from tb_emp,tb_dept where tb_emp.dept_id = tb_dept.id;
内连接:相当于查询A,B交集部分数据
隐式内连接:select 字段列表 from 表1,表2 where 条件 ...;
查询员工的姓名,及所属的部门名称
select tb_emp.name , tb_dept.name from tb_emp,tb_dept where tb_emp.dept_id =
tb_dept.id;
起别名
select e.name,d.name from tb_emp e,tb_dept d where e.dept_id = d.id;
显示内连接:select 字段列表 from 表1 [inner] join 表2 on 连接条件...;
查询员工的姓名,及所属的部门名称
select tb_emp.name , tb_dept.name from tb_emp inner join tb_dept on tb_emp.dept_id = tb_dept.id;
外连接:
左外连接:查询左表所有数据(包括两张表交集部分数据)
select 字段列表 from 表1 left join 表2 on 连接条件...;
查询员工表 所有 员工的姓名,和对应的部门名称
select e.name,d.name from tb_emp e left join tb_dept d on e.dept_id = d.id;
右外连接:查询右表所有数据(包括两张表交集部分数据)
查询部门表 所有 部门的名称,和对应的员工姓名
select e.name,d.name from tb_emp e right join tb_dept d on e.dept_id = d.id;
子查询
SQL语句中嵌套select语句,嵌套查询,又称子查询。
select* from t1 where colurmn1 = (select column from t2 ...);
标量子查询:子查询返回的结果为单个值
子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式
常用的操作符:= <> > >= < <=
-- . 查询 "教研部" 的所有员工信息
-- 1. 查询 教研部 的部门ID - tb_dept
select id from tb_dept where name = '教研部';-- 2. 再查询该部门ID下的员工信息 - tb_emp
select * from tb_emp where dept_id = (select id from tb_dept where name = '教研部');
列子查询:子查询返回的结果为一列 (可以是多行)
常用的操作符:in 、not in等
-- A. 查询 "教研部" 和 "咨询部 " 的所有员工信息
-- a. 查询 "教研部" 和 "咨询部" 的部门ID - tb_dept
select id from tb_dept where name = '教研部' or name = '咨询部';-- b. 根据部门ID, 查询该部门下的员工信息 - tb_emp
select * from tb_emp where dept_id in (select id from tb_dept where name = '教研部' or name = '咨询部');
行子查询:子查询返回的结果是一行(可以是多列)。
常用的操作符:= 、<> 、in 、not in
-- A. 查询与 "韦一笑" 的入职日期 及 职位都相同的员工信息 ;
-- a. 查询 "韦一笑" 的入职日期 及 职位
select entrydate,job from tb_emp where name = '韦一笑';-- b. 查询与其入职日期 及 职位都相同的员工信息 ;
-- 方式一
select * from tb_emp where entrydate = (select entrydate from tb_emp where name = '韦一笑') and job = (select job from tb_emp where name = '韦一笑');-- 方式二
select * from tb_emp where (entrydate,job)=(select entrydate,job from tb_emp where name = '韦一笑');
表子查询:子查询返回的结果是多行多列,常作为临时表
常用的操作符:in
-- A. 查询入职日期是 "2006-01-01" 之后的员工信息 , 及其部门名称
-- a. 查询入职日期是 "2006-01-01" 之后的员工信息
select * from tb_emp where entrydate > '2006-01-01';-- b. 查询这部分员工信息及其部门名称 - tb_dept
select e.* , d.name from (select * from tb_emp where entrydate > '2006-01-01') e , tb_dept d where e.dept_id = d.id;
事务 是一组操作的集合,它是一个不可分割的工作单位。事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作 要么同时成功,要么同时失败。
注意:默认MySQL的事务是自动提交的,也就是说,当执行一条DML语句,MySQL会立即隐式的提交事务。
开启事务:start transaction; / begin ;
提交事务:commit;
回滚事务:rollback;
四大特性
原子性:事务是不可分割的最小单元,要么全部成功,要么全部失败
一致性:事务完成时,必须使所有的数据都保持一致状态
隔离性:数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
持久性:事务一旦提交或回滚,它对数据库中的数据的改变就是永久的
是帮助数据库 高效获取数据 的 数据结构 /树形结构
select * from tb_sku where sn = '100000003145008'; -- 14s
select count(*) from tb_sku;
create index idx_sku_sn on tb_sku(sn);-- 创建 : 为tb_emp表的name字段建立一个索引 .
create [ unique ] index 索引名 on 表名 (字段名,... ) ;
create index idx_emp_name on tb_emp(name);-- 查询 : 查询 tb_emp 表的索引信息 .
show index from 表名;
show index from tb_emp;-- 删除: 删除 tb_emp 表中name字段的索引 .
drop index 索引名 on 表名;
drop index idx_emp_name on tb_emp;
注意:主键字段,在建表时,会自动创建主键索引。
添加唯一约束时,数据库实际上会添加唯一索引。
优点:提高数据查询的效率,降低数据库的IO成本。 通过索引列对数据进行排序,降低数据排序的成本,降低CPU消耗。
缺点:索引会占用存储空间。 索引大大提高了查询效率,同时却也降低了insert、update、delete的效率。
结构:
MySQL数据库支持的索引结构有很多,如:Hash索引、B+Tree索引、Full-Text索引等。我们平常所说的索引,如果没有特别指明,都是指默认的 B+Tree 结构组织的索引。