【MySQL】SELECT语句-语法顺序

1. SELECT 
2. DISTINCT <select_list>
3. FROM <left_table>
4. <join_type> JOIN <right_table>
5. ON <join_condition>
6. WHERE <where_condition>
7. GROUP BY <group_by_list>
8. HAVING <having_condition>
9. ORDER BY <order_by_condition>
10. LIMIT <limit_number>

这些步骤执行时,每个步骤都会产生一张虚拟表,该表被用作下一个步骤的输入。这些虚拟表支持内部操作生效,对外部(客户端程序以及外部查询)不可见。只有最后一步生成表外部才能使用。

1.FROM阶段

  • 求笛卡尔积

也就是我们选取表的阶段,在这个阶段,数据库内部会将表中多个数据通过笛卡尔积生成一个虚表VT1-J1。

  • ON阶段

这个阶段对上个步骤生成的VT1-J1进行筛选,会根据我们ON字句中出现的谓词来进行筛选,插入我们的VT1-J2中。

  • JOIN阶段

通过JOIN将VT1-J2中没有找到匹配的行,作为外部行添加到VT1-J2中,生成VT1-J3。如果FROM子句包含两个以上表,则对上一个连接生成的结果表VT1-J3和下一个表重复依次执行3个步骤,直到处理完所有的表为止。

以上步骤结束后,FROM阶段就完成了。

2.WHERE阶段

WHERE阶段是根据<where_condition>中条件对VT1中的行进行筛选,让条件成立的行才会插入到VT2中。此时数据还没有分组,所以不能再WHERE中出现对统计的过滤。

3. GROUP BY阶段

GROUP阶段按照指定的列名列表,将VT2中的行进行分组,生成VT3。最后每个分组只有一行。在GROUP BY阶段,数据库认为两个NULL值是相等的,因此会将NULL值分到同一个分组中。

4. HAVING阶段

该阶段根据HAVING子句中出现的谓词对VT3的分组进行筛选,并将符合条件的组插入到VT4中。COUNT(expr) 会返回expr不为NULL的行数,count(1)、count(*)会返回包括NULL值在内的所有数量。

5. SELECT阶段

这个阶段是投影的过程,处理SELECT子句提到的元素,产生VT5。这个步骤一般按下列顺序进行:

  • 计算SELECT列表中的表达式,生成VT5-1。
  • 若有DISTINCT,则删除VT5-1中的重复行,生成VT5-2。

6. ORDER BY阶段

根据ORDER BY子句中指定的列明列表,对VT5-2中的行,进行排序,生成VT6。如果不指定排序,数据并非总是按照主键顺序进行排序的。NULL被视为最小值。

7. LIMIT阶段

取出指定行的记录,产生虚拟表VT7,并返回给查询用户。LIMIT n, m的效率是十分低的,一般可以通过在WHERE条件中指定范围来优化 WHERE id > ? limit 10。

猜你喜欢

转载自blog.csdn.net/weixin_43918614/article/details/123260567