一、表的三范式
1.第一范式
(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库,是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值(一个列中只能存储一个值)
帮助理解:
一个列不能有多个值。
必须遵循
2.第二范式
(2NF)要求数据库表中的每个实例或行必须可以被唯一的区分(主键)
帮助理解:
一张表中需要有主键
可遵循可不遵循
3.第三范式
(3NF)要求一个数据库表中包含已在其它表中已包含的主键段信息
帮助理解:一张表的列不能关联别的表的非主键列
可遵循可不遵循
二、过滤查询
空值(重点)
用 NULL 表示,注意:
- 空值是指不可用、未分配的值,也就是没有值;
- 空值不等于零或空格,也不表示空字符串;
- 任意类型都可以支持空值,也就是说任何类型的字段都可以允许空值作为值的存在;
- 包括空值的任何算术表达式都等于空。
- 使用函数 IFNULL(expr1, expr2),若 expr1 不是 NULL,IFNULL() 返回 expr1,否则它返回 expr2
结果排序
ORDER BY 可以使用别名,但不能使用加了引号的别名或列名来排序,没有效果。
执行优先级
优先级规则:比较运算符 > NOT > AND > OR
三、多表查询
1.分类
- 内连接查询
- 隐式内连接查询
- 显示内连接查询
- 外连接查询
- 左外连接查询
- 右外连接查询
- 全外连接查询
2.笛卡尔积
MySQL 中:多表查询会产生笛卡尔积,比如:SELECT * FROM emp, dept,实际运行环境下,应避免使用全笛卡尔集
解决方案:
在 WHERE 语句中加入有效的连接条件 --> 一般是等值连接,注意:连接 n 张表,至少需要 n-1 个连接条件.
3.内连接
①隐式内连接查询
②显示内连接查询(推荐使用)
查询的结果和隐式内连接一模一样。
区别在于:
显示内连接可以看到 [INNER] JOIN;消除笛卡尔积条件使用写在 ON 子句。
4.外连接(重点)
①左外连接:left join…on…
例如:查询出员工的编号,名字,薪水和所在部门的名称(使用内连接查询),执行完会发现,没有部门的员工则查询不出来
查询出 JOIN 左边表的全部数据查询出来,JOIN 右边的表不匹配的数据使用 NULL 来填充数据。
②右外连接:right join…on…
查询出 JOIN 右边表的全部数据查询出来,JOIN 左边的表不匹配的数据使用 NULL 来填充数据。
# 查询交集部分
SELECT 列名1, 列名2, ...
FROM 表1, 表2, ...
WHERE 消除笛卡尔积的条件
# 查询交集部分
SELECT 列名1, 列名2, ...
FROM 表1
JOIN 表2 ON 消除笛卡尔积的条件
JOIN 表3 ON 消除笛卡尔积的条件
...
# 查询交集部分和左边表独有数据
SELECT 列名1, 列名2, ...
FROM 表1
LEFT JOIN 表2 ON 消除笛卡尔积的条件
LEFT JOIN 表3 ON 消除笛卡尔积的条件
...
# 查询交集部分和右边表独有数据
SELECT 列名1, 列名2, ...
FROM 表1
RIGHT JOIN 表2 ON 消除笛卡尔积的条件
RIGHT JOIN 表3 ON 消除笛卡尔积的条件
...
四、分组查询
1.语法
SELECT *
FROM student
[WHERE 条件]
[GROUP BY 分组字段]
[ORDER BY 排序字段 DESC/ASC];
2.分组注意项(重点)
-
SELECT 子句出现的字段,要么在统计函数中,要么不出现在 GROUP BY 子句中,否则不合理(整体与个体);
-
在GROUP BY 子句中出现的字段,可以不出现在 SELECT 列表中;
-
统计函数可以单独使用,SQL 中可以没有 GROUP BY 子句;
-
在 GROUP BY 子句中,可以按单列进行分组,也可以在多列上进行分组,多列分组就是按照多个字段的组合进行分组,最终的结果也会按照分组字段进行排序显示。
-
不能在 WHERE 子句中对分组限定,限制组须使用 HAVING 子句;
-
不能在 WHERE 子句中使用统计函数,而在 HAVING 子句可使用统计函数
五、子查询
1.定义和作用
子查询指的是在一个查询之中嵌套了其他的若干查询
SELECT *
FROM t_student
WHERE g_id = (SELECT * FROM grade [WHERE 条件])
2.注意
子查询一般出现在FROM和WHERE字句重
子查询要使用圆括号括起来
将子查询放在比较运算符的右边
子查询在主查询前执行一次,主查询使用子查询的结果,(建议:不要嵌套太多)
3.分类
按查询结果分类:
- 单行单列:只包含一个字段的查询,返回的查询结果也只包含一行数据;
- 多行单列:只包含了一个字段,但返回的查询结果可能多行或者零行;
- 多行多列:包含多个字段的返回,查询结果可能是单行或者多行,好比是一张表。
单行单列:
子查询结果是一行一列的结果
使用单行记录比较运算符: =、 >、 <、 >=、 <=
多行单列:
子查询结果只有一列,但是有多行。
使用多行比较运算符:
IN
:与列表中的任意一个值相等ANY
:与子查询返回的任意一个值比较
=ANY
:此时和 IN 操作符相同
>ANY
:大于子查询中最小的数据<ANY
:小于子查询中最大的数据ALL
:与子查询返回的每一个值比较>ALL
:大于子查询中最大的数据<ALL
:小于子查询中最小的数据
多行多列:
结果是多行多列,一般会把子查询返回的结果当成一个临时表,接着在临时表上继续查询或者连接查询
注意:多行多列的子查询返回的结果必须要设置一个临时表名。
MySQL执行顺序:
from
where
group by
select
having
order by
limit