where/having查詢
MySQL可以在where子句或者having子句中包含子查詢。包含在圓括號內的子查詢,優先級高於比較和邏輯操作符、in操作符或者 exists操作符。
也可以在一個having子句中的比較運算符前使用子查詢,從而用它對父查詢創建的組進行過濾。
where和having的區別
HAVING是先分組再篩選記錄,WHERE在聚合前先篩選記錄.也就是說作用在GROUP BY 子句和HAVING子句前;而 HAVING子句在聚合後對組記錄進行篩選。
作用的對象不同。WHERE 子句作用於表和視圖,HAVING 子句作用於組。WHERE 在分組和聚集計算之前選取輸入行(因此,它控制哪些行進入聚集計算), 而 HAVING 在分組和聚集之後選取分組的行。因此,WHERE 子句不能包含聚集函數; 因為試圖用聚集函數判斷那些行輸入給聚集運算是沒有意義的。 相反,HAVING 子句總是包含聚集函數。(嚴格說來,你可以寫不使用聚集的 HAVING 子句, 但這樣做只是白費勁。同樣的條件可以更有效地用於 WHERE 階段。)比如說:
select * from tablename where id > 1; 和
select * from tablename having id > 1
這兩者是查詢結果是沒有區別的。不建議使用having
總結就兩句話:
WHERE語句在GROUPBY語句之前;SQL會在分組之前計算WHERE語句。
HAVING語句在GROUPBY語句之後;SQL會在分組之後計算HAVING語句。
in/exists/from查詢
只有子查詢返回的結果列包含一個值時,比較運算符才適用。加入一個子查詢返回的結果集是值的列表, 這時比較運算符就必須用in運算符代替。
in運算符可以檢測結果集中是否存在某個特定的值,如果檢測成功就執行外部的查詢。
exists運算符可以用來查詢一個子查詢是否產生了結果,這使得可以只在exists檢測返回真時才執行外部的查詢
還可以在一個select語句的from子句中把子查詢產生的結果作為一個表。
因而,內查詢產生的結果表用在外查詢的from子句中。這樣的表在sql中成為到導出表。
請注意,當以這種方式使用子查詢的結果時,內查詢產生的結果表必須首先另取一個表名,否則MySQL不知道如何參照其中的列。
in例子
select id,title from article where id in(
428,429,430,431,432
)
exists例子
SELECT c.CustomerId, CompanyName
FROM Customers c
WHERE EXISTS(
SELECT OrderID FROM Orders o
WHERE o.CustomerID = cu.CustomerID)
from例子
select id,title from article where id in(
select article_id from (select article_id from article_tag where tag_id=135) as tbt
)