初学SQL的人都会觉得SQL的关联子查询难以理解,为什么?这是有原因的。
关联子查询的执行逻辑和通常的SELECT语句的执行逻辑完成不一样。这就是SQL关联子查询难以理解的原因。
我们首先来看看正常情况下SELECT的书写顺序和执行顺序: 书写顺序: SELECT》FROM 》WHERE》GROUP BY》HAVE》ORDER BY 执行顺序:
FROM 》WHERE》GROUP BY》HAVE》SELECT》ORDER BY
以下以Product表为例:
执行以下代码说明执行过程:
SELECT product_type,count(*)
FROM Product
WHERE sale_price > 100
GROUP BY product_type
HAVING count(*) > 1
ORDER BY product_type
这里的P1和P2都是指向Product表,都是它的别名,所以P1.product_type 与 P2.product_type必然是相等的,所以这个WHERE字句是废话。 既然是废话,我们删除这句废话看看: SELECT product_type , product_name, sale_price FROM Product AS P1 WHERE sale_price > ( SELECT AVG(sale_price) FROM Product AS P2 GROUP BY product_type); 这个语句是错误的,原因是sale_price是一行数据,子查询的结果是3行数据,无法进行比较。更无法得到我们想要的“选取出各商品种类中高于该商品种类的平均销售单价的商品。”这个结果。 实际上,‘WHERE P1.product_type = P2.product_type’这个语句是关联子查询,关联子查询的执行逻辑和正常的SELECT语句执行逻辑完全不同,这就是它的诡异之处了(不知道规定它的人是怎么想的,搞那么复杂的逻辑)。 下面,我们来说明一下上面的关联子查询代码的执行过程: 记住,关联子查询和正常的SELECT语句完全不同。
先执行主查询
SELECT product _type , product_name, sale_price FROM Product AS P1 结果:
SELECT AVG(sale_price) FROM Product AS P2 WHERE P2.product_type = ‘衣服’ GROUP BY product_type); 第一次子查询结果:
从子查询得到的结果AVG(sale_price)=2500,返回主查询: SELECT product_type , product_name, sale_price FROM Product AS P1 WHERE sale_price > 2500 AND product_type = ‘衣服’ 第一次整个语句的结果: