数据控制语言 (Data Control Language) 它可以控制特定用户账户对数据表、查看表、预存程序、用户自定义函数等数据库对象的控制权。由 GRANT 和 REVOKE 两个指令组成。
MySQL索引
索引是帮助MySQL高效获取数据的数据结构 索引数据结构:二叉树、红黑树、hash表、B-Tree
普通索引:最基本的索引,没什么限制。
唯一索引:索引列的值必须唯一,但允许有空值。
主键索引:一种特殊的索引,一个表只能有一个主键,不允许有空值。
组合索引:指多个字段上创建的索引,使用组合索引遵循最左前缀原则。
全文索引:主要用来查找文本中的关键字,而不是直接与索引中的值比较。
数据查询语言
基础查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# 查单个字段 select dept_name from departments; # 查多个字段 select name, email from employees; # 查所有字段 select*from departments; # 使用表达式 selectdate, employee_id, basic+bonus from salary; # 查询函数,统计salary共有多少行记录 selectcount(*) from salary; # 使用别名,字段名和别名之间可以用空格或关键字AS与as指定别名 select dept_id 部门编号, dept_name AS 部门名 from departments; # 去重 distinct select dept_id from employees; selectdistinct dept_id from employees; # 使用concat函数进行字符串拼接 select concat(name, '-', phone_number) from employees;
条件查询
1 2 3 4 5 6 7 8 9 10
select*from departments where dept_id>3; select*from departments where dept_id<3; select*from departments where dept_id=3; select*from departments where dept_id!=3; select*from departments where dept_id>=3; select*from departments where dept_id<=3;
select*from departments where dept_id>1and dept_id<5; select*from departments where dept_id<3or dept_id>6; select*from departments wherenot dept_id<=6;
模糊查询
like: 包含
between x and y : 在x和y之间的
in:在列表中的
is null:为空,相当于python的None
is not null:非空
%匹配0到多个任意字符
_匹配一个字符
1 2 3 4 5 6 7 8 9 10 11
select name, email from employees where name like'张%';
select name, email from employees where name like'张_';
select*from departments where dept_id between3and5;
select*from departments where dept_id in (1, 3, 5, 8); # 匹配部门名为空的记录 select*from departments where dept_name isnull; # 查询部门名不为空的记录 select*from departments where dept_name isnot null;
排序(默认升序)
1 2 3 4 5
select name, birth_date from employees where birth_date>'19980101'; # 默认升序排列 select name, birth_date from employees where birth_date>'19980101'orderby birth_date; # 降序排列 select name, birth_date from employees where birth_date>'19980101'orderby birth_date desc;
函数
字符函数
LENGTH(str):返字符串长度,以(字节)为单位
1 2 3
select length('abc'); select length('你好'); select name, email, length(email) from employees where name='李平';
select if(3>0, 'yes', 'no'); select name, dept_id, if(dept_id=1, '人事部', '非人事部') from employees where name='张亮';
IFNULL(v1,v2): 如果v1不为NULL,则返回v1,否则返回v2
1 2 3
select dept_id, dept_name, ifnull(dept_name, '未设置') from departments; insert into departments(dept_id) values(9); select dept_id, dept_name, ifnull(dept_name, '未设置') from departments;
CASE expr (WHEN v1)( THEN r1) [WHEN v2 THEN v2] [ELSE rn] END: 如果expr等于某个vn,则返回对应位置THEN后面的结果,如果与所有值都不想等,则返回ELSE后面的rn
1 2 3 4 5 6 7 8
select dept_id, dept_name, case dept_nam when'运维部'then'技术部门' when'开发部'then'技术部门' whennullthen'未设置' else'非技术部门' endas'部门类型' from departments;
1 2 3 4 5 6 7 8
select dept_id, dept_name, case when dept_name='运维部'then'技术部门' when dept_name='开发部'then'技术部门' when dept_name isnullthen'未设置' else'非技术部门' endas'部门类型' from departments;
分组函数
用于统计,又称为聚合函数或统计函数
1 2
# sum/min/count/avg select employee_id, max(basic+bonus) from salary where employee_id=10andyear(date)=2018;
分组查询
语法格式
查询列表必须是分组函数和出现在(GROUP BY)后面的字段
通常而言,分组前的数据筛选放在where子句中,分组后的数据筛选放在having子句中
1 2 3 4 5 6
SELECT 字段名1(要求出现在groupby后面),分组函数(),…… FROM 表名 WHERE 条件 GROUPBY 字段名1,字段名2 HAVING 过滤条件 ORDERBY 字段;
如果直接查询两张表,将会得到笛卡尔积 select name, dept_name from employees, departments;
通过添加有效的条件可以进行查询结果的限定 select name, dept_name from employees, departments where employees.dept_id=departments.dept_id;
语法格式
1 2 3 4 5 6 7 8
SELECT 字段... FROM 表1 [AS] 别名 [连接类型] JOIN 表2 [AS] 别名 ON 连接条件 WHERE 分组前筛选条件 GROUPBY 分组 HAVING 分组后筛选条件 ORDERBY 排序字段
内连接
1 2 3 4 5 6 7 8
select 查询列表 from 表1 别名 innerjoin 表2 别名 on 连接条件 innerjoin 表3 别名 on 连接条件 [where 筛选条件] [groupby 分组] [having 分组后筛选] [orderby 排序列表]
等值连接
查询每个员工所在的部门名,使用别名。两个表中的同名字段,必须指定表名
1 2 3 4
select name, d.dept_id, dept_name from employees as e innerjoin departments as d on e.dept_id=d.dept_id;
查询2018年总工资大于30万的员工,按工资降序排列
1 2 3 4 5 6 7
select name, sum(basic+bonus) as total from employees as e innerjoin salary as s on e.employee_id=s.employee_id whereyear(s.date)=2018 groupby name having total>300000 orderby total desc;
select grade, count(*) from salary as s innerjoin wage_grade as g on s.basic between g.low and g.high whereyear(date)=2018andmonth(date)=12 groupby grade;
查询2018年12月员工基本工资级别,员工需要显示姓名
1 2 3 4 5 6 7 8
select name, date, basic, grade from salary as s innerjoin employees as e on s.employee_id=e.employee_id innerjoin wage_grade on basic between low and high wheredate='20181210' orderby grade, basic;
自连接
将一张表作为两张使用
每张表起一个别名
查看哪些员的生日月份与入职月份相同
1 2 3 4 5
select e.name, e.hire_date, em.birth_date from employees as e innerjoin employees as em onmonth(e.hire_date)=month(em.birth_date) and e.employee_id=em.employee_id;
外连接的概述
常用于查询一个表中有,另一个表中没有的记录
如果从表中有和它匹配的,则显示匹配的值
如要从表中没有和它匹配的,则显示NULL
外连接查询结果=内连接查询结果+主表中有而从表中没有的记录
左外连接中,left join左边的是主表left outer join
右外连接中,right join右边的是主表right outer join
左外连接和右外连接可互换,实现相同的目标
左外连接
语法
1 2 3 4
SELECT tb1.字段..., tb2.字段 FROM table1 AS tb1 LEFTOUTERJOIN table2 AS tb2 ON tb1.字段=tb2.字段
查询所有部门的人员以及没有员工的部门
1 2 3 4
select d.*, e.name from departments as d leftouterjoin employees as e on d.dept_id=e.dept_id;
右外连接
查询所有部门的人员以及没有员工的部门
1 2 3 4
select d.*, e.name ->from employees as e ->rightouterjoin departments as d ->on d.dept_id=e.dept_id;
left join和right join 的区别
left join(左连接):查询结果为两个表匹配到的数据,左表特有的数据,对于右表中不存在的数据使用null填充。