核心:本章知识回顾下基础,对于复杂的查询,单独列出来,放后面续备案。
select其实也算DML,但是select需要单独拉出看。
select是sql中最复杂的,它是一个筛选操作,但是是工程级别的筛选操作。
这个数据筛选可以是简单的单标单字段,还可以是多表各种子查询 结果记录集的筛选,甚至还要包含各种聚合和析构函数。
当然还是本着实用的观点,先简单的认识下这个select,执行计划暂时不涉及。
基本语法:
SELECT *
FROM tablename
[where condition]
这个语句就是结构化淋漓尽致体现的样本。
- FROM 从哪里
- where根据什么条件
- SELECT 得到哪些信息。
‘*’ 表示所有列,开发调试常用,正式项目禁用,按需查询,不要动不动查询所有列而不考虑资源消耗。
往往调试的时候除了使用 ‘*’ 还要limit一下,因为有些工具不自动分页,查询一个500G的表等于作死。
select * from t_employee limit 10;
开启简单模式,先认识下我们常规操作。
1、去重查询
select distinct ename from t_employee limit 10;
select count(distinct ename) from t_employee limit 10;
例如统计下研发上报了多少鲲鹏主机,就可以这么用下。
2、条件查询
很多时候用户不会要所有记录,而是根据条件查询下记录。
SELECT
*
FROM
t_node_agent t
WHERE
t.f_flag = 2
AND t.f_host_name LIKE 'dgg\_fm%';
where查询经常用到一些运算符,常用的有
- >
- <
- >=
- <=
- =
- !=
- or
- and
3、排序和限制
排序是业务工程几乎必须用的东西,我们往往会把最新记录放到第一页。
SELECT * FROM tablename [WHERE CONDITION|ORDER BY field1[DESC|ASC],field2[DESC|ASC]...fieldn[DESC|ASC]];
- DESC 降序
- ASC 升序 默认
select * from t_employee t ORDER BY t.sal is null, t.em_id desc;
上面这个排序有意思了,把某个字段为空的,放到最后面。
例如执行引擎自动下发脚本,把系统参数放到最后面。
SELECT ...[LIMIT offset_start,row_count]
分页很重要,每天面对mysql oracle分页都忘记了
这里不是起始记录数:
- offset_start–从第几行开始
- row_count–取多少行记录
select * from t_employee t ORDER BY t.em_id desc LIMIT 2,2;
注意:limit属于MYSQL扩展SQL92后的语法,在其他数据库上并不能通用。
4、聚合
SELECT [field1,field2...fieldn] fun_name
from tablename
[WHERE where condition]
[group by field1,field2...fieldn]
[with rollup]
[HAVING where condition]
- fun_name 表示要做的聚合操作,也就是聚合函数,常用的有sum、count、max、min
- group by 关键字表示要进行分类聚合的字段,比如要按照部门分类统计员工数量,部门就应该写在group by后面。
- with rollup 是可选语法,表明是否对分类聚合后的结果进行再汇总。
- Having 关键字表示分类后的结果再进行条件的过滤。
注意:having和where的区别在于,having是对聚合后的结果进行条件的过滤,而where是在聚合前就对记录进行过滤,聚过逻辑允许,我们尽可能用where先过滤记录,这样因为结果集减小,将对聚合的效率大大提高,最后再根据逻辑看是否用having进行再过滤。
5、连接表
当需要同时显示多个表中的字段时,就可以用连接表实现这样的功能。
从大类上分,表连接分为内连接和外连接,它们之间的最主要的区别是,内连接仅选出两张表中相互配合的记录。而外连接会选出其他不匹配的记录。
我们最常见的是内连接。
查询所有员工名称和所在部门名称
SELECT
e.ename,
d.dept_name
FROM
t_emp e,
t_dept d
WHERE
e.dept_no = d.dept_no
上面这种就是内连接,最常见的关联查询模式。
外连接又分为左连接和右连接
- 左连接:包含所有的左边表中的记录,甚至是右边表中没有和它匹配的记录。
- 右连接:包含所有的右边表中的记录,甚至是左边表中没有和它匹配的记录。
左右连接其实是一个意思,区别知识谁在前面,谁在后面的问题。
查询所有的员工和部门信息
SELECT
e.ename,
dept_name
FROM
t_emp e
LEFT JOIN t_dept d ON e.dept_no = d.dept_no
6.、子查询
看到子查询就会想到性能,oracle策略树比较强大,在硬编译的时候会做一些调整,谓词推入等。mysql使用起来真的尽可能的加好索引,减少子查询。
所谓的子查询,就是独立一个sql块获取结果记录集,用于子查询的关键字主要包括:
in 、not in、=、!=、exists、not exists等。
例如:查询拥有部门的所有员工信息
SELECT
*
FROM
t_emp e
WHERE
e.dept_no IN ( SELECT d.dept_no FROM t_dept d )
还是一个原则,能用连接完成的就用连接。
7、记录联合
就是把两个查询结果记录集进行合并,前提是两个记录结果集数据结构一致,即列名相同,数据类型兼容。
常见的是union和union all,oracle还可以求交集minus。
select e.dept_no from t_emp e
union
select d.dept_no from t_dept d;
select e.dept_no from t_emp e
union all
select d.dept_no from t_dept d
union 会去重,去重就会用到sort,消耗较多的内存和IO。
union all 不会去重,直接两部分结果记录集进行合并。