前言
SELECT 可以说是 SQL 最常用的语句了,下面来看一下 SELECT 的基本使用方法。
查询列
SELECT 列名称 FROM 表名称
起别名
使用AS关键字
SELECT name AS n
去除重复行
使用DISTINCT关键字
SELECT DISTINCT 列名称 FROM 表名称
使用DISTINCT需要注意的两个点:
- DISTINCT 需要放到所有列名的前面。
- DISTINCT其实是对后面所有列名的组合进行去重。
排序检索数据
使用ORDER BY需要掌握以下几个点:
- 排序的列名:ORDER BY后面可以有一个或多个列名,多个列名排序时,会按照第一个列先进行排序
- 排序的顺序:ORDER BY后面可以注明排序规则,ASC代表递增排序,DESC代表递减排序。默认时按照ASC递增排序。
- 非选择列排序:ORDER BY可以使用非选择列进行排序,即使在SELECT后面没有这个列名,同样可以放到OEDER BY后面进行排序。
约束返回结果的数量
使用LIMIT关键字
SELECT 列名称 FROM 表名称 LIMIT 5
SELECT 的执行顺序
SELECT 查询时的两个顺序:
- 关键字的顺序不能颠倒:
SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ...
- SELECT 语句的执行顺序:
FROM > WHERE > GROUP BY > HAVING > SELECT 的字段 > DISTINCT > ORDER BY > LIMIT
SELECT DISTINCT player_id, player_name, count(*) as num # 顺序 5
FROM player JOIN team ON player.team_id = team.team_id # 顺序 1
WHERE height > 1.80 # 顺序 2
GROUP BY player.team_id # 顺序 3
HAVING num > 2 # 顺序 4
ORDER BY num DESC # 顺序 6
LIMIT 2 # 顺序 7
SQL 的执行原理
SELECT 先执行 FROM 这一步的。在这个阶段,如果是多张表联查,还会经历下面的几个步骤:
-
首先先通过 CROSS JOIN 求笛卡尔积,相当于得到虚拟表 vt(virtual table)1-1;
-
通过 ON 进行筛选,在虚拟表 vt1-1 的基础上进行筛选,得到虚拟表 vt1-2;
-
添加外部行。如果我们使用的是左连接、右链接或者全连接,就会涉及到外部行,也就是在虚拟表 vt1-2 的基础上增加外部行,得到虚拟表 vt1-3。
如果操作的是两张以上的表,还会重复上面的步骤,直到所有表都被处理完为止。这个过程得到是原始数据。
当拿到了查询数据表的原始数据,也就是最终的虚拟表 vt1,就可以在此基础上再进行 WHERE 阶段。在这个阶段中,会根据 vt1 表的结果进行筛选过滤,得到虚拟表 vt2。
然后进入第三步和第四步,也就是 GROUP 和 HAVING 阶段。在这个阶段中,实际上是在虚拟表 vt2 的基础上进行分组和分组过滤,得到中间的虚拟表 vt3 和 vt4。
当完成了条件筛选部分之后,就可以筛选表中提取的字段,也就是进入到 SELECT 和 DISTINCT 阶段。
首先在 SELECT 阶段会提取想要的字段,然后在 DISTINCT 阶段过滤掉重复的行,分别得到中间的虚拟表 vt5-1 和 vt5-2。
当提取了想要的字段数据之后,就可以按照指定的字段进行排序,也就是 ORDER BY 阶段,得到虚拟表 vt6。
最后在 vt6 的基础上,取出指定行的记录,也就是 LIMIT 阶段,得到最终的结果,对应的是虚拟表 vt7。
当然在写 SELECT 语句的时候,不一定存在所有的关键字,相应的阶段就会省略。
关于SELECT *
如果只是练习或者对数据表进行探索,可以使用SELECT *。
生产环境尽量避免使用SELECT *进行查询。