本文内容全文参考 https://www.bilibili.com/video/BV12b411K7Zu
- DQL(Data Query Language):数据查询语言,用来查询记录(数据)。
1.基础查询
SELECT column_name,column_name FROM table_name
2.条件查询
- 条件查询就是在查询时给出WHERE子句,在WHERE子句中可以使用如下运算符及关键字:
- =、!=、<>、<、<=、>、>=;
- AND、OR、NOT
- BETWEEN…AND、IN(set)、IS NULL
SELECT column_name,column_name
FROM table_name
WHERE Clause
- 查询语句中你可以使用一个或者多个表,表之间使用逗号(,)分割,并使用WHERE语句来设定查询条件。
- SELECT 命令可以读取一条或者多条记录。
- 你可以使用星号(*)来代替其他字段,SELECT语句会返回表的所有字段数据
- 你可以使用 WHERE 语句来包含任何条件。
3.模糊查询
3.1 like
- 在 where like 的条件查询中,SQL 提供了四种匹配方式。
- %:表示任意 0 个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示。
- _:表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句。
- []:表示括号内所列字符中的一个(类似正则表达式)。指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。
- [^] :表示不在括号所列之内的单个字符。其取值和 [] 相同,但它要求所匹配对象为指定字符以外的任一个字符。
- 查询员工信息表中姓名第一个字符为e的员工信息
SELECT * FROM employee WHERE ename LIKE 'E%';
- 查询员工信息表中姓名第二个字符为e,第五个字符为a的员工信息
SELECT * FROM employee WHERE ename LIKE '_E__A%';
3.2 between and
- ①用于筛选某个字段或表达式是否在指定的区间范围
- ②等价于 使用逻辑表达式的效果,只是语法上更加简单
- ③两个区间值不能调换顺序
3.3 in
- 查询员工信息表中姓名是HH或是ZZ的员工信息
SELECT * FROM employee WHERE ename in ('ZZ','HH')
3.3 is null
- 查询哪个员工没有奖金
SELECT *
FROM employees
WHERE commission_pct IS NULL
4.字段控制查询
4.1去除重复记录
- 如果你需要读取不重复的数据可以在 SELECT 语句中使用 DISTINCT 关键字来过滤重复数据。
SELECT DISTINCT last_name, first_name FROM person_tbl;
防止表中出现重复数据,表中设置指定的字段为 PRIMARY KEY(主键) 或者 UNIQUE(唯一) 索引来保证数据的唯一性。
4.2 判断字段是否为NULL
- IFNULL() 函数用于判断第一个表达式是否为 NULL,如果为 NULL 则返回第二个参数的值,如果不为 NULL 则返回第一个参数的值。
- IFNULL() 函数语法格式为:IFNULL(v1,v2)
- 如果 v1 不为 NULL,则 IFNULL 函数返回 v1; 否则返回 v2 的结果。
4.3 给列名添加别名
方式一:
select 列名 as 别名 from 表名;
方式二:
select 列名 别名 from 表名;
5.排序 order by
-
order by 默认是升序(ASC),降序是DESC;
-
按工资从低到高排序
SELECT *
FROM employee
ORDER BY salary ASC
6.常见函数
7.聚合(分组)函数
- 聚合函数是用来做纵向运算的函数:
- COUNT():统计指定列不为NULL的记录行数
- MAX():计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算
- MIN():计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算
- SUM():计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0
- AVG():计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0
8.分组查询
8.1 简单的分组
- 查询每个工种的员工平均工资
SELECT AVG(salary) 平均工资
from employees
GROUP BY job_id
8.2 可以实现分组前的筛选
- 查询邮箱中包含a字符的 每个部门的最高工资
SELECT MAX(salary) 最高工资
FROM employees
WHERE email LIKE '%a%'
GROUP BY job_id
- 查询每个领导手下有奖金的员工的平均工资
SELECT AVG(salary) 平均工资
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id
8.3 可以实现分组后的筛选
- 查询哪个部门的员工个数>5
SELECT COUNT(*) 员工个数,department_id
FROM employees
GROUP BY department_id
HAVING 员工个数>5
8.4 可以实现排序
- 每个工种有奖金的员工的最高工资>6000的工种编号和最高工资,按最高工资升序
SELECT job_id,MAX(salary) 最高工资
FROM employees
GROUP BY job_id
HAVING MAX(salary)>6000
ORDER BY 最高工资
8.5 按多个字段分组
- 查询每个工种每个部门的最低工资,并按最低工资降序
SELECT job_id,department_id,MIN(salary) 最低工资
FROM employees
GROUP BY job_id,department_id
ORDER BY 最低工资 DESC
9.连接查询
9.1 内连接
SELECT * FROM emp e INNER JOIN dept d ON e.deptno=d.deptno;
- 注意:inner可以省略、on是连接条件
- 内连接的特点:查询结果必须满足条件。
9.2 外连接(左连接、右连接、全外连接)
9.2.1 左连接
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.deptno=d.deptno;
- 注意:OUTER可以省略
- 左连接是先查询出左表(即以左表为主),然后查询右表,右表中满足条件的显示出来,不满足条件的显示NULL。
9.2.2 右连接
- 右连接就是先把右表中所有记录都查询出来,然后左表满足条件的显示,不满足显示NULL。例如在dept表中的40部门并不存在员工,但在右连接中,如果dept表为右表,那么还是会查出40部门,但相应的员工信息为NULL。
SELECT * FROM emp e RIGHT OUTER JOIN dept d ON e.deptno=d.deptno;
9.2.3 全外连接
SELECT 查询列表
FROM 表1 表名
FULL【OUTER】 JOIN 表2 表名
ON 连接条件
9.3 自然连接(不常用)
- 大家也都知道,连接查询会产生无用笛卡尔积,我们通常使用主外键关系等式来去除它。而自然连接无需你去给出主外键等式,它会自动找到这一等式:
- 两张连接的表中名称和类型完成一致的列作为条件,例如emp和dept表都存在deptno列,并且类型一致,所以会被自然连接找到!
- 当然自然连接还有其他的查找条件的方式,但其他方式都可能存在问题!
SELECT * FROM emp NATURAL JOIN dept;
SELECT * FROM emp NATURAL LEFT JOIN dept;
SELECT * FROM emp NATURAL RIGHT JOIN dept;
10.子查询
10.1 概念
- 出现在其他语句的内部的select语句,称为子查询或内查询
- 里面嵌套其他select语句的查询语句,称为主查询或外查询
子查询不一定必须出现在select语句内部,只是出现在select语句内部的时候较多!
select first_name from employees where department_id >(
select department_id from departments
where location_id=1700
)
- 1、子查询语句需要放在小括号内,提高代码的阅读性
- 2、子查询先于主查询执行,一般来讲,主查询会用到子查询的结果
- 3、如果子查询放在条件中,一般来讲,子查询需要放在条件的右侧
- 示例:where job_id>(子查询)
- 不能写成:where (子查询)<job_id
10.2 分类
单行子查询
- 特点:子查询的结果集只有一行一列
- 单行子查询对应的使用单行操作符:> < >= <= = <>
多行子查询
- 特点:子查询的结果集有多行一列
- 多行子查询对应的使用多行操作符:in 、any 、all 、not in
#查询各部门中员工工资比所在部门的平均工资高的员工的工号、姓名和工资。
#第一步:各部门的平均工资
SELECT
department_id,
AVG(salary) 平均工资
FROM
employees
GROUP BY
department_id;
#第二步:将第一步的结果和employees表连接查询
SELECT
employee_id,
e.department_id,
last_name,
salary
FROM
employees e
JOIN (
SELECT
department_id,
AVG(salary) 平均工资
FROM
employees
GROUP BY
department_id
) dep_ag ON e.department_id = dep_ag.department_id
WHERE
e.salary > dep_ag.`平均工资`;
#查询和姓名中包含字母u的员工在相同部门的员工的员工号和姓名
#第一步:查询姓名中包含字母u的员工的部门编号
SELECT DISTINCT
department_id
FROM
employees
WHERE
last_name LIKE '%u%';
#第二步:查询部门号是①的部门号和姓名
SELECT
department_id,
last_name
FROM
employees
WHERE
department_id IN (
SELECT DISTINCT
department_id
FROM
employees
WHERE
last_name LIKE '%u%'
);
#查询管理者是K_ing的员工姓名和工资
#①查询管理者是K_ing的员工编号
SELECT
employee_id
FROM
employees
WHERE
last_name = 'K_ing';
#②查询哪个员工的领导编号是①的员工姓名和工资
SELECT
last_name,
salary
FROM
employees
WHERE
manager_id IN (
SELECT
employee_id
FROM
employees
WHERE
last_name = 'K_ing'
);
#查询平均工资最低的部门信息和该部门的平均工资
#①查询各部门的平均工资
SELECT
department_id,
AVG(salary) 平均工资
FROM
employees
GROUP BY
department_id;
#② 连接①和departments表,在进行排序和分页
SELECT
d.*, 平均工资
FROM
departments d
JOIN (
SELECT
department_id,
AVG(salary) 平均工资
FROM
employees
GROUP BY
department_id
) avg_de ON d.department_id = avg_de.department_id
ORDER BY
平均工资
LIMIT 1;
#各个部门中 最高工资中最低的那个部门的 最低工资是多少
#①查询各部门的最高工资中最低的部门的编号和工资
SELECT
department_id
FROM
employees
GROUP BY
department_id
ORDER BY
MAX(salary)
LIMIT 1;
#②查询部门编号是①的部门的最低工资
SELECT
MIN(salary) 最低工资
FROM
employees
WHERE
department_id = (
SELECT
department_id
FROM
employees
GROUP BY
department_id
ORDER BY
MAX(salary)
LIMIT 1
);
11.分页查询
select 查询列表
from 表
【where 条件】
limit 【起始条目索引,】查询的条目数;
12.联合查询
- MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions];
- expression1, expression2, … expression_n: 要检索的列。
- tables: 要检索的数据表。
- WHERE conditions: 可选, 检索条件。
- DISTINCT: 可选,删除结果集中重复的数据。默认情况下 UNION 操作符已经删除了重复数据,所以 DISTINCT 修饰符对结果没啥影响。
- ALL: 可选,返回所有结果集,包含重复数据。