数据的简单查询
无条件查询记录、字段的计算和字段的别名
数据的高级查询
数据排序、分页、去除重复记录
数据的有条件查询
条件表达式:数学运算符、比较运算符、逻辑运算符、按位运算符
1.数据操作语言:普通查询
记录查询
-
最基本的查询语句是由SELECT和FROM关键字组成的:
SELECT * FROM t_emp; SELECT empno,ename,sal FROM t_emp;
SELECT 语句屏蔽了物理层的操作,用户不必关心数据的真实存储,交由数据库高效的查找数据。
-
使用列别名
通常情况下,SELECT子句中使用了表达式,那么这列名字就默认为表达式,因此需要一种对列名重命名的机制:
SELECT empno, sal*12 AS "income" # AS 就去取别名,可以省略 sal*12 "income"这样是一样的效果 FROM t_empno; # 查询了每名员工的年收入情况结果为:
empno <font color="red">income</font> 7369 9600.00 7499 19200.00 取别名只是对结果集有影响,对数据库本身没有任何影响。
SELECT empno, sal*12 FROM t_empno; # 如果直接这样查询,那么结果集中年收入的字段名就直接是:sal*12:
empno <font color="red">sal*12</font> 7369 9600.00 查询语句的子句执行顺序
<font color="red">先执行FROM子句确定数据来源,再执行SELECT子句选择输出到结果集中的字段。</font>
mysql执行sql语句,不是从左到右执行的,而是先做词法分析优化,提取出各种子句,然后根据优先级再来执行!
2.数据操作语言:数据分页
-
如果结果集很多,则可以使用LIMIT关键字限定结果集数量
SELECT ..... FROM .....LIMIT 起始位置,偏移量; SELECT empno,ename FROM t_emp LIMIT 0,20; # 0为起始位置,往后取20条记录 SELECT empno,ename FROM t_emp LIMIT 20,20; # 代表查20-40的数据。 后一位的20是代表偏移量。
这里需要注意,查询后20条数据,并不是LIMIT 20,40.
-
如果LIMIT子句只有一个参数,它表示的是偏移量,起始值默认为0:
# 下面两个语句是等价的 SELECT empno,ename FROM t_emp LIMIT 10; SELECT empno,ename FROM t_emp LIMIT 0,10;
执行顺序:FROM->SELECT->LIMIT
3.数据操作语言:结果集排序
如果想让结果集按照某种顺序排列,就必须使用ORDER BY子句
SELECT ..... FROM ..... ORDER BY 列名 [ASC|DESC]
# ASC 升序排列 DESC 降序排列 如果不写 默认是ASC升序排列
SELECT ename,sal FROM t_emp ORDER BY sal; # 默认是ASC排列
1.排序关键字
ASC代表升序(默认),DESC代表降序
-
如果排序列是数字类型,数据库就按照数字大小排序,如果是日期类型就按照日期大小排序,如果是字符串就按照字符集序号排序。
SELECT ename,sal,hiredate FROM t_emp ORDER BY hiredate DESC;
2.多个排序字段
默认情况下,如果两条数据排序字段内容相同,那么排序会是什么样子?例如根据工资排序两条记录工资是相同的,默认情况下是根据主键排序的。
可以使用ORDER BY规定首要排序条件和次要排序条件。如果多个条件都无法排序,最终会按照主键大小来排序
# 多个排序条件,当sal字段值相同时,就按照hiredate字段值来升序排序
SELECT empno,ename,sal,hiredate FROM t_emp ORDER BY sal DESC,hiredate ASC;
empno | ename | sal | hiredate |
---|---|---|---|
7839 | KING | 5000.00 | 1981-11-17 |
7902 | FORD | 3000.00 | 1981-12-03 |
7788 | SCOTT | 3000.00 | 1982-12-09 |
可以看到得到的结果集,当sal字段值相同时,就按照hiredate字段值来升序排序。
查询公司中工资排在前五位的员工信息
SELECT * FROM t_emp ORDER BY sal DESC LIMIT 5;
SELECT name,enrollment_date,tuition from student ORDER BY tuition asc,enrollment_date asc
排序+分页关键字的执行顺序:
FROM->SELECT->ORDER BY->LIMIT
4.数据库操作语言:去除重复记录
1.去除重复的数据,可以使用DISTINCT关键字来实现
SELECT DISTINCT 字段 FROM ......;
SELECT DISTINCT job FROM t_emp; # 数据表中的数据是不会改变的,只是对结果集去重。
2.DISTINCT使用注意事项
-
使用DISTINCT的SELECT子句中只能查询一列数据,如果查询多列,去除重复记录就会失效。
# 这种情况去重就会失效 SELECT DISTINCT job,name FROM t_emp;
-
DISTINCT关键字只能在SELECT子句中使用一次
# 这种是错误的语法 SELECT DISTINCT job,DISTINCT ename FROM t_emp; # 写在第二个字段前面,也是错误的用法 SELECT ename,DISTINCT job FROM t_emp;
5.数据库操作语言:条件查询
用WHERE子句来实现数据的筛选
# 多个条件必须满足,条件之间用AND连接,只需满足其中一个用OR连接
SELECT ...... FROM ...... WHERE 条件 [AND|OR] 条件 ......;
SELECT empno,ename,sal FROM t_emp WHERE deptno = 10 and sal >= 2000;
SELECT empno,ename,sal FROM t_emp WHERE (deptno = 10 OR deptno = 20) and sal >= 2000;
WHERE语句中的条件运算会用到一下四种运算符:
数学运算符、比较运算符、逻辑运算符、按位运算符
1.算数运算符
序号 | 表达式 | 意义 | 例子 |
---|---|---|---|
1 | + | 加法 | 1 + 2 +3 |
2 | - | 减法 | 8 - 5 |
3 | * | 乘法 | 1 * 6 |
4 | / | 除法 | 9 / 3 |
5 | % | 求模 | 10 %3 |
# 查询工龄大于等于20年,年薪超过15000的员工
SELECT empno,ename,sal,hiredate
FROM t_emp
WHERE deptno=10 AND (sal+IFNULL(comm,0))*12>=15000 # 和null做运算结果都是null,所以需要用IFNULL()来过滤
AND DATEDIFF(NOW(),hiredate)/365>=20 # NOW() 获取的是当前时间
2.比较运算符
序号 | 表达式 | 意义 | 例子 |
---|---|---|---|
1 | > | 大于 | Age > 18 |
2 | >= | 大于等于 | Age >=18 |
3 | < | 小于 | sal < 3000 |
4 | <= | 小于等于 | sal <= 3000 |
5 | = | 等于 | Deptno = 10 |
6 | != | 不等于 | deptno != 30 |
7 | In | 包含 | Deptno IN(10,20,30) |
# 查询1985年前入职的员工,而且不是销售岗位的员工
SELECT empno,ename,job,sal,deptno,hiredate
FROM t_emp
WHERE deptno IN(10,20,30) AND job != "SALESMAN" AND hiredate < "1985-01-01"
序号 | 表达式 | 意义 | 例子 |
---|---|---|---|
8 | IS NULL | 为空 | comm IS NULL |
9 | IS NOT NULL | 不为空 | comm IS NOT NULL |
10 | BETWEEN AND | 范围 | sal BETWEEN 2000 AND 3000 |
11 | LIKE | 模糊查询 | ename LIKE "A%" (%表示0到多个字符都匹配) |
12 | REGEXP | 正则表达式 | ename REGEXP "[a-zA-Z]{4}" |
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}$";
3.逻辑运算符
序号 | 表达式 | 意义 | 例子 | 解释 |
---|---|---|---|---|
1 | AND | 与关系 | age > 18 AND sex = "男" | AND两边条件都必须满足 |
2 | OR | 或关系 | empno = 8000 OR deptno = 20 | 两个条件只需满足一个即可 |
3 | NOT | 非关系 | NOT deptno = 20 | 表示查找部门编号不是20的员工(等价于:deptno != 20) |
4 | XOR | 异或关系 | Age > 18 XOR sex = "男" | <font color="red">两边条件同时成立结果为false,两边结果不同就为true</font> |
# 查询10、20 之外的员工
SELECT ename,sal,deptno
FROM t_emp
WHERE NOT deptno IN(10,20)
4.二进制按位运算
二进制位运算的实质是将参与运算的两个操作数,按对应的二进制数逐位进行逻辑运算。
例如 SELECT 3 & 7
0 | 0 | 1 | 1 | 3的二进制 | |
---|---|---|---|---|---|
0 | 1 | 1 | 1 | 7的二进制 | |
& 都为1时结果才为1 | 0 | 0 | 1 | 1 | 结果为3 |
| 只要有一个为1结果就为1 | 0 | 1 | 1 | 1 | 结果为7 |
按位运算符
序号 | 表达式 | 意义 | 例子 |
---|---|---|---|
1 | & | 位与关系 | 3 & 7 |
2 | | | 位或关系 | 3 | 7 |
3 | ~ | 位取反 | ~10 |
4 | ^ | 位异或 | 3 ^ 7 |
5 | << | 左移 | 10 << 1 |
6 | >> | 右移 | 10 >> 1 |
WHRE子句的注意事项。
WHERE子句中,条件执行的顺序是从左到右的。所以我们应该把索引条件,或者筛选记录最多的条件卸载最左侧。这样可以提升查询速度。
# 先过滤大部分数据。再精确查询,以此来提高查询效率
SELECT empno,ename FROM t_emp WHERE ename = "FORD" AND sal >= 2000;
SELECT empno,ename FROM t_emp WHERE deptno = 10 AND sal >= 2000;
WHERE子句的条件优先级:索引条件放在最左边,其次是筛选最多记录的条件,最后是普通的检索条件
条件查询中,WHERE子句应该是第几个执行?
FROM -> WHERE -> SELECT -> ORDER BY -> LIMIT
总结:
- 掌握select子句的列别名和去除重复记录
- 掌握数据排序语法
- 掌握数据分页的语法
- 掌握有条件查询的语法和运算符