- where在查詢數據庫結果返回之前對查詢條件進行約束,就是結果返回之前起作用,而having是查詢數據庫,已經得到返回的結果了,再對結果進行過濾。(結果返回前,結果返回后)
- where條件不能使用聚合函數,想想也能明白因為聚合函數是已經返回的結果,having后面可以使用聚合函數;
- where后面接的必須是表中有的字段,查詢結果中可以沒有;但是having后面接的字段必須是返回的結果中有的,查詢的表中有沒有無關;(不理解這句話可以參考:原文)
- 使用where子句,可以對條件中用到的字段創建索引,提高查詢效率。
-
當在Where子句和Having子句中都可以使用的條件,從語句的執行效率來看,最好使用Where子句。
在使用Count函數等對表中的數據進行聚合操作時,DBMS內部會進行排序處理,而排序操作會增加機器的負擔,減少排序的行數,可以增加處理速度。
使用Where子句指定條件時,由於排序之前就對數據進行了過濾,所以能夠減少排序的數據量。但是Having子句是在排序之后才對數據進行分組的,因此與前者相比,需要排序的數據量就要多得多。
- 做了一個測試,建了一個學生分數表。
然后查詢所有科目都大於80分的學生姓名,我先用的這條語句:select name,fenshu from stu group by name having fenshu > 80; 查詢結果如圖:
和預期結果不一樣,having是對查詢出來的結果進行過濾,而且我這里還根據名字分組了,本以為having是在每個分組內逐行比較,當所有行都滿足條件的時候才返回。現在看來並不是這樣的,having應該是只比較每個分組內的第一條數據,如果滿足條件就返回。至於分組內的其他記錄不比較了。所以上面的語句執行結果返回的是三個學生都滿足。我把王五的語文改成70分,數學改成90,結果是沒有王五,也說明了having確實只比較分組內的第一條數據,其他的不比較。 那么正確語句是select name from stu group by name having name not in ( select name from stu where fenshu <80);
這個是查詢到所有分數大於80的學生姓名。 又測試了一下select name from stu group by name having name in ( select name from stu where fenshu >80); 把not去掉,fenshu>80 結果和前兩條語句都不一樣,這個是只要有至少一門大於80分就可以返回。