目录
[toc]
一、课程介绍
1.1 select语句
数据库是用来存储数据的,那么怎么按照特定的条件,从数据库中查询出我们想要的数据呢?
数据库提供了SQL语言,其中:
- DDl:管理逻辑库、数据表
- DCL:创建用户
接下来学习DML:select语句.
因为软件大部分是读多写少,所以数据的查询语法也是最多最灵活的。
1.2 学习任务
(1)数据的简单查询
只有select-from两个关键字
(2)数据的高级查询
排序、分页、去重
(3)数据的条件查询
条件表达式:四类运算符
二、数据库的基本查询
2.1 基本查询
1.运行已有SQL文件
创建新的逻辑库:demo
,运行SQL文件。
得到四张表:
2.基本查询的语法
- 基本查询语句是由
SELECT-FROM
关键字组成
USE demo; # 切换到demo这个逻辑空间
SELECT * FROM t_emp; # 查询所有的字段
SELECT empno,ename,sal FROM t_emp; # 查询指定字段
- SELECT语句屏蔽了物理层的查找,用户不关心数据的存储方式,查询工作交给数据库系统去完成。
短短的一条SQL语句,就能从成千山万的数据中,检索到我们需要的记录。真牛真方便
3.使用列别名
(1)语法
SELECT字句中如果使用了运算表达式,那么列名默认就是表达式本身。有时看着不优雅,因此需要对列名进行重命名。
AS
(2)案例
- 列名默认就是表达式本身
- 用
AS
关键字,对列名进行重命名
注意,上述只是对结果集中的字段修改名称,并不会对底层数据表的字段修改名称。
4.子句执行顺序
2.2 数据分页
1.必要性
生活场景;
打开微信朋友圈,只会加载少量部分信息,而不是一次性向微信服务器请求全部的朋友圈信息。因为那样会非常消耗网络流量、服务器的硬件资源。
因此,限定结果集的数据数量,应运而生。
2.语法
LIMIT
表示限定的是前20条记录
注意:上面的是偏移量,而不是数据的结束位置
3.案例演示
SELECT empno,ename FROM t_emp LIMIT 0,5; # 只选前5条记录
SELECT empno,ename FROM t_emp LIMIT 10,5; # 从下标10位置起,选5条记录
结果如下:
4.简写
如果LIMIT子句只有1个参数,那么它表示偏移量,起始值默认是0。
5.子句执行顺序
FROM--->SELECT--->LIMIT
因为SELECT规定了结果集出现的字段,只有有了结果集,才能限制结果集中显示的数量。
所以,SELECT在LIMIT之前。
2.3 数据排序
1.必要性
默认情况下,查询语句不会对结果集进行排序。所以,如果要想让结果集按照特定顺序排列,就要使用ORDER BY子句。
2.语法
ORDER BY
如果没有明确表示升序还是降序,默认情况下按照升序。
3.案例演示
SELECT empno,ename,sal,deptno FROM t_emp ORDER BY sal; # 对工资进行升序排列
SELECT empno,ename,sal,deptno FROM t_emp ORDER BY sal DESC; # 对工资进行降序排列
结果如下:
对工资进行降序排列
4.排序支持的字段类型
不管什么类型的字段,都可以排序:
- 排序列是数字型---------按照数字大小排序
- 排序列是日期型---------按照日期大小排序
- 排序列是字符串型------按照字符集的序号排序
SELECT empno,ename,hiredate,deptno FROM t_emp ORDER BY ename ASC; # 按照名字升序
SELECT empno,ename,hiredate,deptno FROM t_emp ORDER BY hiredate DESC; # 按照雇佣日期降序
- 按照名字升序
- 按照雇佣日期降序
5.排序字段内容相同的情况
当排序后出现两条数据相同,那么默认按照主键大小再排序
6.多个排序字段
主要排序,次要排序
(1)演示1
SELECT empno,ename,sal,hiredate FROM t_emp ORDER BY sal DESC,hiredate; # 先按工资降序,如果有重复的就按雇佣日期升序
(2)演示2
SELECT
empno,ename,deptno,sal
FROM t_emp
ORDER BY deptno,sal DESC; # 先按照部门升序,有重复的再按工资降序
7.排序+分页
SELECT
empno,ename,sal
FROM t_emp
ORDER BY sal DESC LIMIT 0,5; # 按工资降序+值显示前五条记录
8.子句执行顺序
FROM--->SELECT--->ORDER BY--->LIMIT
当然是,先把字段列所有的数据排序结束后,才能提取前几位。
2.4 数据去重
1.必要性
第二范式(唯一性)要求,数据表必须有主键字段,所以数据表中一定没有重复记录。
但是,结果集就不一样了:如果SELECT子句中没有选择主键字段,那么结果集中就很有可能出现重复的记录。如下:
那么,该如何去除数据集中的这些重复的记录呢?
2.语法
在字段之前加上DISTINCT
关键字
3.案例演示
SELECT DISTINCT job FROM t_emp;
结果如下:
4.注意事项
(1)SELECT DISTINCT 子句中,只能查询一列数据。如上。
如果查询多列,DISTINCT 的去重效果就会失效。
SELECT DISTINCT job,ename FROM t_emp; # ❌
(2)SELECT DISTINCT 子句中,DISTINCT 关键字只能使用一次。如上。
SELECT DISTINCT job,DISTINCT ename FROM t_emp; # ❌
SELECT job,DISTINCT ename FROM t_emp; # ❌
三、数据库的条件查询
因为很多时候,用户感兴趣的并不是数据表里所有的记录,而是满足某一种或某几种条件的记录。
此时,就需要用到条件查询:where
子句。
3.1 语法及案例
1.语法
where+条件表达式
2.案例演示1:
SELECT empno,ename,sal
FROM t_emp
WHERE deptno=10 AND sal>=2000;
结果如下:
3.案例演示2:
SELECT empno,ename,sal
FROM t_emp
WHERE (deptno=10 OR deptno=20) AND sal>=2000;
结果如下:
上面的 where+条件表达式
,使用了AND、OR
两个运算符。接下来,学习更多的运算符。
四、 四类运算符
4.1 分类
where
子句中的查询条件,需要用到四类运算符。
4.2 算术运算符
1.分类
跟python相同。比较好理解。
2.案例演示:
在员工表t_emp
中,查询10部门中,年收入不少于15000且工龄不少于20年的记录?
SELECT empno,ename,sal,hiredate
FROM t_emp
WHERE deptno=10 AND (sal+IFNULL(comm,0))*12>=15000 # 加法、乘法、除法
AND DATEDIFF(NOW(),hiredate)/365>=20;# 两个日期相减,用DATEDIFF()函数将天数转换为年份 # NOW()函数代表现在日期
根据三个条件,成功查询到了如下记录:
3.其中:遇到null的特殊情况:
如果直接相加,就会出错:
SELECT 10+null;
SELECT 10*null; # null不能直接跟数字型进行运算
--->
没有任何正常的结果
修改为:
SELECT 10+IFNULL(null,0);
SELECT 10*IFNULL(NULL,0); # 用IFNULL()函数,如果字段值是null,就转换为0
4.3 比较运算符
1.第一批:
跟python相同。比较好理解。
其中,这里的IN
是包含之意,满足其中之一即可。小括号中,只能是一组数据,即一列数据。
2.案例演示
在员工表t_emp
中,查询10、20、30部门中,1985年以前入职的员工,且不能是saleman职位的记录?
SELECT
empno,ename,sal,deptno,hiredate
FROM t_emp
WHERE deptno IN(10,20,30) AND job!="SALESMAN" # IN()表示包含
AND hiredate<"1985-01-01";
结果如下:
3.第二批
其中,
(1)关于占位符百分号%
:表示0或任意字符,所以:
A%
表示以A开头的名字,
%A
表示以A结尾的名字
%A%
表示名字中有A,无论是开头、结尾,还是中间
(2)关于占位符:_
代表一个字符
比如,某个人的名字除了第一个字母忘记怎么拼,其他都知道
(3)正则表达式:
更高级更牛,是一种抽象的表达式
4.案例演示
在员工表t_emp
中,查询佣金为空、工资在2000-3000之间、名字中有A的记录?
SELECT
ename,COMM,sal
FROM t_emp
WHERE comm IS NULL # 用了IS NULL运算符
AND sal BETWEEN 2000 AND 3000
AND ename LIKE "%A%";
演示下正则表达式:
SELECT
ename,COMM,sal
FROM t_emp
WHERE comm IS NOT NULL
AND sal BETWEEN 1000 AND 3000
AND ename REGEXP "^[\\u4e00-\\u9fa5]{2,4}$"; # 名字是中文,且名字长度是2-4之间
其中,^
表示字符串开头;$
表示字符串结尾。
4.4 逻辑运算符
1.分类
用来定义各个表达式之间的逻辑关系
其中:
异或关系有点特别:
如果两端的表达式结果不相同,那么异或出来的结果就为true;
如果两端的表达式结果相同,那么异或出来的结果就为false;
感觉像零和博弈,我赢你就输,我输你就赢。抛开同赢同输,让其一直处于竞争状态。
2.案例应用
SELECT
ename,deptno
FROM t_emp
WHERE NOT deptno IN (10,20) XOR sal>=2000; # 二者必符合其一
4.5 二进制按位运算
MySQL除了可以进行逻辑运算,还可以按照二进制进行按位运算。
用的比较少。
五、WHERE子句的注意事项
5.1 条件放置的顺序
WHERE子句中,条件执行的顺序是从左到右的。所以,
(1)应该把索引条件,放在最左侧(速度快);
(2)应该把筛选掉记录最多的条件,放在最左侧(筛选效率高):
5.2 各种子句的执行顺序
FROM--->WHERE--->SELECT--->ORDER BY--->LIMIT
只有根据条件筛选出符合条件的记录,才能进一步显示挑选的字段内容。这样也更高效。
Comments | NOTHING