查询操作
文章目录
- 查询操作
- ++[MySQL官网](https://dev.mysql.com/doc/refman/8.0/en/subqueries.html)++
-
- 一、SQL查询语法
-
- 1.基本结构
- 2.select子句
- 3.where子句
-
- [**条件表达式:** 条件形式`like模糊查询`](#条件表达式: 条件形式
like模糊查询
)
- [**条件表达式:** 条件形式`like模糊查询`](#条件表达式: 条件形式
- [二、 聚合函数](#二、 聚合函数)
- 三.排序,分组,分组筛选
- 四.连接查询
-
- [1、 SQL连接分类:](#1、 SQL连接分类:)
-
- 1)inner jon内连接inner jon内连接)
- 2)left joinleft join)
- 3)right joinright join)
- 4)cross joincross join)
- 五、子查询
- [六. MySQL分页`LIMIT`(重点)](#六. MySQL分页
LIMIT
(重点))
++MySQL官网++
一、SQL查询语法
查询产生一个虚拟表,看到的是表形式显示的结果,但结果并不真正存储,每次执行查询只是现从数据表中提取数据,并按照表的形式显示出来。
1.基本结构
sql
SELECT
#查询字段
[ALL | DISTINCT | DISTINCTROW ]
select_expr [, select_expr] ...
[into_option]
[FROM table_references]
#查询条件
[WHERE where_condition]
#分组
[GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
#对分组数据进行筛选
[HAVING where_condition]
#排序: desc降序, 默认asc升序
[ORDER BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
#分页
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
2.select子句
使用以下几种方式指定字段列表:
字段列表 | 说明 |
---|---|
* | 字段列表为数据源的全部字段 |
表名.* | 多表查询时,指定某个表的全部字段 |
字段列表 | 指定所需要显示的列 |
sql
select * from tb_name #查询表中全部字段
select col_name from tb_name; #查询表中个别字段数据
select tb_name.col_name from tb_name;#多表查询时,字段前加入表名
3.where子句
where条件语句;后面跟着筛选数据的条件
条件表达式: 条件形式like模糊查询
关键字 | 解释 |
---|---|
比较运算符 | 单一条件过滤 |
逻辑运算符 | 组合多个条件查询 |
BETWEEN AND | 在两数之间 |
NOT BETWEEN AND | 不在两数之间 |
IN <值表> | 是否在特定的集合里(枚举) |
NOT IN <值表> | 与上面相反 |
LIKE concat() |
- 是否匹配于一个模式 - 拼接字符串 |
IS NULL | 为空的 |
IS NOT NULL | 不为空的 |
Binary | 区分大小写 |
-
比较运算符
=(等于)、>(大于)、>=(大于等于)、<(小于)、<=(小于等于)、<>(不等于)、!=(不等于)
sql#举例: 查询条件薪资大于9000的员工 select * from employee where salary>9000;
-
逻辑运算符
逻辑与(and)、逻辑或(or)以及逻辑非(not),其中逻辑非(not)为单目运算符。
sql#查询条件: 查询年龄18以上工资大于9000的员工 select * from employee where age>18 and salary>9000;
-
IS NULL运算符
is NULL用于判断表达式的值是否为空值NULL(is not 恰恰相反)
sql#查询地址为空的员工姓名 SELECT emp_name As 姓名, address AS 地址 FROM EMPLOYEE WHERE address IS NULL;
-
BETWEEN AND
把某一字段中内容在特定范围内的记录查询出来
sql#查询年龄在18~50的员工 select * from employee where age between 18 and 50;
-
IN
sql#查询年龄为18,30和50的员工,满足任意1个年龄即查询 select * from employee where age in(18,30,50);
-
模糊查询
like
(重点难点模糊点)like运算符用于判断一个字符串是否与给定的模式相匹配;(
like concat(arg0,arg1....)
拼接字符串)通配符 含义 % 指定位置有零个或多个字符 _ 指定位置有1个 sql#查询首字为张的姓名的员工 SELECT * FROM EMPLOYEE WHERE emp_name LIKE '张%'; #查询员工姓名第二个字是牛的员工信息 SELECT * FROM EMPLOYEE WHERE emp_name LIKE '_牛%'; -- 查询员工中姓名第二字是"子"的员工 SELECT * from employee WHERE emp_name LIKE CONCAT('_','子','%'); SELECT * from employee WHERE emp_name LIKE '_子%';
BINARY运算符: 区分大小写
默认情况,模糊查询不区分大小写,可以添加BINARY关键字让MySQL执行区分大小写的比较
sqlSELECT * FROM emp WHERE emp_name LIKE BINARY '%tom%';
二、 聚合函数
min(),max(),sum(),avg(),count()
函数 | 介绍 |
---|---|
SUM() | 求总和,只适用于数值类型字段,如果是字符串类型不会报错会返回0,会自动过滤空值 |
AVG() | 求平均值,只适用于数值类型字段,字符串类型不会报错会返回0,会自动过滤空值 |
MAX() | 求最大值,适用于数值类型、字符串类型和日期时间类型字段 |
MIN() | 求最小值,适用于数值类型、字符串类型和日期时间类型字段 |
COUNT() | 用于计算查询结果集中的数据共有多少条 |
sql
-- 查询员工的最低工资是多少
SELECT MIN(salary) FROM employee;
-- 查询员工的最大年龄
SELECT MAX(age) from employee;
-- 查询工资总和
SELECT SUM(salary) from employee;
-- 统计员工人数
SELECT COUNT(emp_id) from employee;
-- 统计员工平均工资
SELECT AVG(salary) from employee;
三.排序,分组,分组筛选
-
group by
sql-- 单列分组 -- 统计每个部门人数 SELECT dept_id,COUNT(emp_id) AS 人数 from employee WHERE dept_id is NOT NULL GROUP BY dept_id; -- 多列分组 -- 统计每个部门不同学历的员工有多少人,该怎么办? SELECT dep_id AS 部门编号,degree AS 学历, count(*) AS 人数 FROM EMPLOYEE GROUP BY dep_id,degree ORDER BY dep_id
-
order by col_name [desc | asc]
排序: 默认asc升序, desc降序
sql-- 统计每个部门人数,根据部门人数进行升序排序 SELECT dept_id,COUNT(emp_id) AS 人数 from employee WHERE dept_id is NOT NULL GROUP BY dept_id ORDER BY COUNT(emp_id);
-
HAVING
对分组后的数据进行排序,后面可以跟聚合函数
sql-- 统计每个部门人数,根据部门人数进行升序排序,并筛选部门人数大于1的部门 SELECT dept_id,COUNT(emp_id) AS 人数 from employee WHERE dept_id is NOT NULL GROUP BY dept_id HAVING COUNT(emp_id)>1 ORDER BY COUNT(emp_id);
WHERE和HAVING的区别?
- WHERE子句从数据源中去掉不符合其搜索条件的数据,跟在表名后面,后面不跟聚合函数
- HAVING子句去掉不符合其组搜索条件的各组数据行(对分组后的数据进行筛选)
sql
-- 完整的sql语句
select dept_id, count(*) from employee
where dept_id is not null -- 对所有数据进行筛选,不能使用聚合函数,筛选id不为空的数据,第一道筛选数据
GROUP BY dept_id -- 对where筛选后的数据进行分组
having count(*)>2 -- 对分组后的数据进行再筛选第二道
order by dept_id desc; -- 对数据根据id进行降序排序
四.连接查询
1、 SQL连接分类:
-
inner连接(内连接)
inner join...on
组合多表记录,返回关联字段相符的记录(交集部分)
-
outer连接(外连接)
left | right join...on
- left(左外连接,简称为左连接)
- right(右外连接,简称为右连接)
-
cross连接(交叉连接)
across join...on
1)inner jon内连接
合并具有同一列的两个以上的表的行,结果集中不 包含一个表与另一个表不 匹配的行(*<u>**显示都符合二者条件的记录**
*)
合并具有共同字段的记录,没有共同字段的不显示记录 ;(比如说: employee有员工没有归属某个部门,则没有对应的部门id,则内连接不显示此员工的记录数据)
sql
-- 内连接: 返回符合交集的记录,e是employee表另起名
SELECT * from employee e
INNER JOIN dept d
on e.dept_id=d.dept_id;
2)left join
左表(a_table)的记录将会全部表示出来,而右表(b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NULL。
sql
-- 左外连接
SELECT * from employee e
LEFT JOIN dept d
ON e.dept_id=d.dept_id;
注意: 左表employee显示全部数据右表dept没有符和条件(二者dept_id相等)的显示为空null
3)right join
左表e只会显示符合搜索条件的记录,而右表d的记录将会全部表示出来。左表记录不足的地方均为NULL。
sql
-- 右连接
SELECT * from employee e
RIGHT JOIN dept d
ON e.dept_id=d.dept_id;
注意: e表没有dept_id属性值的记录显示为空
4)cross join
多表都符合条件显示记录,类似内连接
sql
SELECT * from employee e
CROSS JOIN dept d
ON e.dept_id=d.dept_id;
-- 等价于
select * from employee e,dept d where e.dept_id=d.id;
select * from employee e INNER JOIN dept d on e.dept_id=d.id;
五、子查询
0.定义:
实质就是>>嵌套查询语句
- 子查询的 SELECT 查询总是使用圆括号括起来。
- 子查询可以嵌套在外部 SELECT、INSERT、UPDATE 或 DELETE 语句的 WHERE 或 HAVING 子句内,或者其它子查询中。
- 根据可用内存和查询中其它表达式的复杂程度不同,嵌套限制也有所不同,嵌套到 32 层。
sql
-- 子查询: 查询工资大于平均工资的员工姓名
SELECT emp_name from employee WHERE salary>(SELECT AVG(salary) FROM employee);
1.多行比较操作符
操作符 | 含义 |
---|---|
IN | 等于列表中的任意一个 |
ANY | 需要和单行比较操作符一起使用,和子查询返回的某一个值比较 |
ALL | 需要和单行比较操作符一起使用,和子查询返回的所有值比较 |
SOME | 实际上是ANY的别名,作用相同,一般常使用ANY |
2.子查询可出现的位置
位置 | 类型 | 说明 |
---|---|---|
select后面: | 仅仅支持标量子查询 | 作为一个字段值 |
from后面: | 支持表子查询 | 作为一个临时表 |
where或having后面: | 支持标量子查询(单行)、列子查询(多行)、行子查询 | 作为过滤条件 |
exists后面(也被称为'相关子查询') | 支持表子查询 | 判断条件是否存在 |
3.SQL语句举例:
sql
-- 查询等于任意部门最低工资的员工记录(in)
select * from employee where salary in (select min(salary) from employee GROUP BY dept_id);
-- 查询大于任意一个部门最低工资的员工信息
select * from employee where salary>any (select min(salary) from employee GROUP BY dept_id);
-- 大于所有部门最低工资的员工信息
select * from employee where salary>all (select min(salary) from employee GROUP BY dept_id);
-- 没有员工的部门信息,SELECT * FROM employee e WHERE d.dept_id=e.dept_id查询有部门的员工记录,不存在查询部门信息(not exists)
SELECT * FROM dept d
WHERE NOT EXISTS(SELECT * FROM employee e WHERE d.dept_id=e.dept_id);
-- 查询有员工的部门(exists)
select * from dept d where EXISTS (select * from employee e where d.dept_id=e.dept_id );
六. MySQL分页LIMIT
(重点)
sql
-- 格式: 第一个数字>>起始行数,第二个数字>>展现记录行数
select字段列表 from数据源 limit [start,]length;
-- 分页功能
-- 限制查询limit
-- 查询前5条数据
SELECT * from employee LIMIT 5;
-- 查询前五条后面的五条数据(6~10)
SELECT * from employee LIMIT 5,5;
-- 也可以通过id唯一标识符先进行筛选数据,再分页
d where EXISTS (select * from employee e where d.dept_id=e.dept_id );
## 六. MySQL分页`LIMIT`(重点)
~~~sql
-- 格式: 第一个数字>>起始行数,第二个数字>>展现记录行数
select字段列表 from数据源 limit [start,]length;
-- 分页功能
-- 限制查询limit
-- 查询前5条数据
SELECT * from employee LIMIT 5;
-- 查询前五条后面的五条数据(6~10)
SELECT * from employee LIMIT 5,5;
-- 也可以通过id唯一标识符先进行筛选数据,再分页