目录 一、准备工作 二、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)