重慶分公司,新征程啟航
為企業提供網站建設、域名注冊、服務器等服務
為企業提供網站建設、域名注冊、服務器等服務
前幾天工作上遇到一個問題,在mysql數據查詢的時候,使用的是in條件,而結果需要根據in來進行排序,當時嘗試了幾次都沒成功,后來在度娘的幫助下,找到了解決辦法:
成都創新互聯公司自成立以來,一直致力于為企業提供從網站策劃、網站設計、成都網站建設、網站制作、電子商務、網站推廣、網站優化到為企業提供個性化軟件開發等基于互聯網的全面整合營銷服務。公司擁有豐富的網站建設和互聯網應用系統開發管理經驗、成熟的應用系統解決方案、優秀的網站開發工程師團隊及專業的網站設計師團隊。
select * from table_name where id in (6,2,1,10,5,7..)
查詢的結果和in中的順序并不一致,也就是說在批量查詢時,mysql的查詢并不是按照in中的值得順序來查詢的。那怎么才能保證和in查詢中的順序相同呢?
查詢了資料發現有兩種方式可以對in查詢的結果進行排序。一種是order by find_in_set,另外一種是order by substring_index
1、select * from table_name where id in (6,2,1,10,5,7..) order by find_in_set(id,'6,2,1,10,5,7');
2、select * from table_name where id in (6,2,1,10,5,7..)?order by substring_index('6,2,1,10,5,7',id,1);
上一篇聚合函數末尾處使用了GROUP BY,但沒有做具體的介紹,這一篇就主要介紹一下GROUP BY的使用方法。順便介紹一下對分組查詢的過濾關鍵詞HAVING的用法。
在MySQL中,GROUP BY關鍵詞可以根據一個或多個字段對查詢結果進行分組,類似于Excel中的數據透視表。可以單獨使用,但一般情況下都是結合聚合函數來使用的。
語法格式如下:
下面演示都是基于這一張簡單的省份對應大區的表格。
【單獨使用GROUP BY】
單獨使用GROUP BY關鍵字時,查詢結果會只顯示每個分組的第一條記錄。
根據省份表里面的大區進行聚合,查詢全國共分成了幾個大區,SQL語句如下↓
【GROUP BY結合聚合函數】
5個聚合函數上一篇已經詳細介紹了用法,GROUP BY和聚合函數結合使用也是最頻繁的,下面就繼續使用省份表來求每個大區有多少個省份,對應的聚合函數就是COUNT函數,SQL語句如下↓
【GROUP BY結合GROUP_CONCAT】
這還是一個很有用的功能,GROUP_CONCAT() 函數會把每個分組的字段值都合并成一行顯示出來。
下面繼續使用省份表,把每個大區對應的省份放在一行展示,用分號分開,SQL語句如下↓
【GROUP BY結合WITH ROLLUP】
WITH POLLUP關鍵詞用來在所有記錄的最后加上一條記錄,這條記錄是上面所有記錄的總和,SQL語句如下↓
【GROUP BY結合HAVING】
在MySQL中,可以使用HAVING關鍵字對分組后的數據進行過濾。
使用 HAVING 關鍵字的語法格式如下:
HAVING關鍵詞和WHERE關鍵詞都可以用來過濾數據,且HAVING支持WHERE關鍵詞中所有的操作符和語法。但是WHERE和HAVING關鍵字也存在以下幾點差異:
下面篩選一下省份數量在7個及以上的大區,SQL語句如下↓
【GROUP BY結合ORDER BY】
聚合后的數據,一半情況下也是需要進行排序的,通過ORDER BY對聚合查詢結果進行排序,對省份數量按從大到小進行排序,SQL語句如下↓
End
◆ PowerBI開場白
◆ Python高德地圖可視化
◆ Python不規則條形圖
對結果進行排序操作的代價可能很高,因此可以通過避免排序或讓參與排序的數據行更少來優化查詢性能。
當 MySQL 不能使用索引產生有序結果時,它必須對數據行進行排序。這有可能是在內存中進行也可能是在磁盤進行,但 MySQL 始終將這個過程稱之為 filesort,即便實際上并沒有使用一個文件。
如果用于排序的值可以一次性放入排序緩存中,MySQL 可以在內存中使用快排算法進行排序。如果 MySQL 不能在內存中進行排序,則會在磁盤中按塊逐塊排序。它對每個塊使用快排算法,然后在將這些排序好的塊合并到結果中。
有兩個文件排序(filesort)算法:
很難說哪種算法更有效,對每個算法來說都會有最優和最壞案例。MySQL 在數據表全部列加上用于排序的列的大小不超過 max_length_for_sort_data 時會使用單次遍歷算法。可以通過修改這個參數影響排序算法的選擇。
需要注意的是,MySQL 的 filesort使用的臨時存儲空間可能會超出你的預期,這是因為它對每個排序元素都分配了固定大小的存儲空間。這些存儲空間要足夠大以便容下存儲最大的元素,而且 VARCHAR這類字段使用的是對應的最大長度。而且,如果使用的是 UTF-8字符集,MuSQL 會對每個字符分配3個字節。結果是,我們會發現那些沒怎么優化的查詢會導致磁盤上的臨時存儲空間是數據表自身存儲空間的好幾倍。
而在對聯合查詢進行排序時,MySQL 可能會在查詢執行過程中執行兩次文件排序。如果 ORDER BY 子句只是引用聯合查詢的第一張表,MySQL 可以先對這個表進行文件排序,然后再處理聯合查詢。如果是這種情況,在 EXPLAIN 時會在 Extra 字段顯示“Using filesort”。而對于其他的排序情況——例如排序不是針對第一張表,或者是 ORDER BY 使用的列對應了不止一個數據表,MySQL 必須使用臨時表緩存查詢結果,然而在聯合查詢完成后,再對臨時表進行文件排序。在這種情況下,EXPLAIN 會在 Extra 字段顯示“Using temorary; Using filesort”。如果包含 LIMIT 約束的話,會發生在文件排序后,因此臨時表和文件排序的存儲空間可能非常大。
MySQL 5.6在只需要對數據行的子集(例如 LIMIT)進行排序時,引入了一個重大改進。相對于對整個結果集進行排序再返回部分數據,MySQL 有時候會在排序的時候直接丟棄掉不需要的數據行來提高效率。不管怎么樣,排序也需要小心使用,很可能會導致存儲占用的飆升最終導致系統負荷過大。
在MySQL中,可以指定按照多個字段進行排序。例如,可以使employee表按照d_id字段和age字段進行排序。排序過程中,先按照d_id字段進行排序,遇到d_id字段的值相等的情況時,再把d_id值相等的記錄按照age字段進行排序。
查詢employee表中的所有記錄,按照d_id字段的降序方式和age字段的升序方式進行排序。