SQL语句执行顺序

转自:https://blog.csdn.net/freeking101/article/details/76522504

准备工作

SELECT DISTINCT 
FROM 
 JOIN 
ON 
WHERE 
GROUP BY 
HAVING 
ORDER BY 
LIMIT 

继续做以下的前期准备工作:
1.新建一个测试数据库TestDB;

 create database TestDB;

2.创建测试表table1和table2;

 CREATE TABLE table1
 (
     customer_id VARCHAR(10) NOT NULL,
     city VARCHAR(10) NOT NULL,
     PRIMARY KEY(customer_id)
 )ENGINE=INNODB DEFAULT CHARSET=UTF8;
 
 CREATE TABLE table2
 (
     order_id INT NOT NULL auto_increment,
     customer_id VARCHAR(10),
     PRIMARY KEY(order_id)
 )ENGINE=INNODB DEFAULT CHARSET=UTF8;

3.插入测试数据;

 INSERT INTO table1(customer_id,city) VALUES('163','hangzhou');
 INSERT INTO table1(customer_id,city) VALUES('9you','shanghai');
 INSERT INTO table1(customer_id,city) VALUES('tx','hangzhou');
 INSERT INTO table1(customer_id,city) VALUES('baidu','hangzhou');
 
 INSERT INTO table2(customer_id) VALUES('163');
 INSERT INTO table2(customer_id) VALUES('163');
 INSERT INTO table2(customer_id) VALUES('9you');
 INSERT INTO table2(customer_id) VALUES('9you');
 INSERT INTO table2(customer_id) VALUES('9you');
 INSERT INTO table2(customer_id) VALUES('tx');
 INSERT INTO table2(customer_id) VALUES(NULL);

准备工作做完以后,table1和table2看起来应该像下面这样:

 mysql> select * from table1;
 +-------------+----------+
 | customer_id | city     |
 +-------------+----------+
 | 163         | hangzhou |
 | 9you        | shanghai |
 | baidu       | hangzhou |
 | tx          | hangzhou |
 +-------------+----------+
 4 rows in set (0.00 sec)
 
 mysql> select * from table2;
 +----------+-------------+
 | order_id | customer_id |
 +----------+-------------+
 |        1 | 163         |
 |        2 | 163         |
 |        3 | 9you        |
 |        4 | 9you        |
 |        5 | 9you        |
 |        6 | tx          |
 |        7 | NULL        |
 +----------+-------------+
 7 rows in set (0.00 sec)

4.准备SQL逻辑查询测试语句

 SELECT a.customer_id, COUNT(b.order_id) as total_orders
 FROM table1 AS a
 LEFT JOIN table2 AS b
 ON a.customer_id = b.customer_id
 WHERE a.city = 'hangzhou'
 GROUP BY a.customer_id
 HAVING count(b.order_id) < 2
 ORDER BY total_orders DESC;

使用上述SQL查询语句来获得来自杭州,并且订单数少于2的客户。

SQL逻辑查询语句执行顺序

那么,到底哪个先执行,哪个后执行呢?现在,先给出一个查询语句的执行顺序:


(7)     SELECT                             /* 处理SELECT列表,产生 VT7 */
(8)     DISTINCT              /* 将重复的行从 VT7 中删除,产品 VT8 */
(1)     FROM                   /* 对FROM子句中的表执行笛卡尔积(交叉联接),生成虚拟表 VT1。*/
(3)      JOIN      /* 如果指定了OUTER JOIN(相对于CROSS JOIN或INNER JOIN),
                                              保留表中未找到匹配的行将作为外部行添加到 VT2,生成 VT3。
                                              如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表位置。*/
(2)     ON                 /* 对 VT1 应用 ON 筛选器,只有那些使条件为真的行才被插入到 VT2。*/
(4)     WHERE             /* 对 VT3 应用 WHERE 筛选器,只有使条件为真的行才插入VT4。*/
(5)     GROUP BY            /* 按 GROUP BY子句中的列列表对 VT4 中的行进行分组,生成 VT5。*/
(6)     HAVING           /* 对 VT5 应用 HAVING 筛选器,只有使为true的组插入到 VT6 。*/
(9)     ORDER BY       /* 将 VT8 中的行按 ORDER BY子句中的列列表顺序,生成一个游标(VC9)。*/
(10)    LIMIT                /*生成表VT10,并返回给调用者。*/

Oracle SQL语句执行顺序

(8)SELECT (9)DISTINCT  (11)