sql语句执行步骤详解

目录

  • 一、准备工作
  • 二、SQL逻辑查询语句执行顺序
  • 三、SQL书写习惯

一、准备工作

先来一段伪代码,首先你能看懂么?

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

继续做以下的前期准备工作:

新建一个测试数据库TestDB;

create database TestDB;

创建测试表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;

插入测试数据;

 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)

准备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逻辑查询语句执行顺序

还记得上面给出的那一长串的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 筛选器,只有使为true的行才插入VT4。 */
    (5) GROUP BY    /* 按 GROUP BY子句中的列列表对 VT4 中的行进行分组,生成 VT5 */
    (6) HAVING   /* 对 VT5 应用 HAVING 筛选器,只有使为true的组插入到 VT6 */
    (9) ORDER BY   /* 将 VT8 中的行按 ORDER BY子句中的列列表顺序,生成一个游标(VC10),
      生成表TV11,并返回给调用者。 */
    (10)LIMIT 

Oracle SQL语句执行顺序

    (8)SELECT (9)DISTINCT  (11)