Correlated Subqueries
Nested SubQueries
相關子查詢是一個子查詢中引用了某張表且這張表也在子查詢外部被使用到。好比:html
SELECT * FROM t1 WHERE column1 IN ( SELECT column1 FROM t2 WHERE t2.column2 = t1.column2);
請注意子查詢有一個t1表column2的引用,儘管子查詢的from語句中沒有涉及t1表,這時mysql執行子查詢卻發現t1表在外部查詢中。mysql
假設表t1有一行數據(column1=5,column2=6),與此同時表t2有一行數據(column1=5,column2=7)。sql
若是是簡單的子查詢:性能
... WHERE column1 = ANY (SELECT column1 FROM t2)
結果將會是true,有數據返回。可是在這個例子中,where子句中的子查詢會返回false,查不到任何數據,由於兩張表的column2不匹配。code
相關子查詢
和普通子查詢
(也叫非相關子查詢
)的差異就在於這子查詢中是否有對外部查詢中涉及到的表的引用。htm
規則範圍: MySQL從內到外執行執行。好比:ip
SELECT column1 FROM t1 AS x WHERE x.column1 = (SELECT column1 FROM t2 AS x WHERE x.column1 = (SELECT column1 FROM t3 WHERE x.column2 = t3.column1));
在這條語句中,x.column2
必定是表t2的列,由於查詢SELECT column1 FROM t2 AS x ...
別名是x,它不是表t1的列是由於SELECT column1 FROM t1 ...
是一個外部查詢。它倆中間還隔着一對圓括號。get
相關子查詢是使用外部查詢中的值的子查詢(嵌套在另外一個查詢中的查詢)。由於子查詢需爲外部查詢返回的每一行執行一次,因此它可能會很慢。io
SELECT employee_number, name FROM employees emp WHERE salary > ( SELECT AVG(salary) FROM employees WHERE department = emp.department);
在上面的查詢中,外部查詢爲:class
SELECT employee_number, name FROM employees emp WHERE salary > ...
內部查詢(相關子查詢)爲:
SELECT AVG(salary) FROM employees WHERE department = emp.department
在上面的嵌套查詢中,須爲每一個員工從新執行內部查詢。
看完官方和Wiki的解釋,對相關子查詢的描述基本同樣,用本身的話說就是:
相關子查詢被用來作逐行的處理,子查詢會爲外部查詢出來的每一行執行內部SQL。(外部語句也可爲update或delete語句)
可拆分紅下面三個步驟: