Group by隱式排序,一個優美的BUG,當上項目經理才知道

程序猿阿娜 2021-09-19 12:09:23 阅读数:637

group 排序 美的 bug 知道

??核對代碼時我們發現,老版本Select語句中只是用到了Group by分組,也沒有用到order by排序,有點蒙,為啥沒用order by卻排了序?查資料後得知,在MySQL8.0版本前是存在Group by隱式排序的! 就是說在我們使用分組(Group by)時,如:select * from T group by appName; 會默認按照appName正序排序,相當於select * from T group by appName order by appName;,倒排同理:select * from T group by appName desc; 可見,MySQL在8.0版本前的分組查詢中,偷偷加上了排序操作。

??納尼?MySQL還有這種操作?快找一下官方文檔對Group by隱式排序的介紹:

[](

)官方文檔


官方文檔MySQL 5.7 Reference Manual中的“2.1.14 ORDER BY Optimization”章節有如下介紹:

GROUP BY implicitly sorts by default (that is, in the absence of ASC or DESC designators for GROUP BY columns). However, relying on implicit GROUP BY sorting (that is, sorting in the absence of ASC or DESC designators) or explicit sorting for GROUP BY (that is, by using explicit ASC or DESC designators for GROUP BY columns) is deprecated. To produce a given sort order, provide an ORDER BY clause.

google翻譯:默認情况下GROUP BY隱式排序(即,缺少GROUP BY列的ASC或DESC指示符)。但是,不推薦依賴於隱式GROUP BY排序(即,在沒有ASC或DESC指示符的情况下排序)或GROUP BY的顯式排序(即,通過對GROUP BY列使用顯式ASC或DESC指示符)。要生成給定的排序 ORDER,請提供ORDER BY子句。

??從MySQL 8.0開始,GROUP BY字段不再支持隱式排序. 官方文檔MySQL 8.0 Reference Manual中“8.2.1.16 ORDER BY Optimization”章節有如下介紹:

Previously (MySQL 5.7 and lower), GROUP BY sorted implicitly under certain conditions. In MySQL 8.0, that no longer occurs, so specifying ORDER BY NULL at the end to suppress implicit sorting (as was done previously) is no longer necessary. However, query results may differ from previous MySQL versions. To produce a given sort order, provide an ORDER BY clause.

google翻譯:以前(MySQL 5.7及更低版本),GROUP BY在某些條件下隱式排序。 在MySQL 8.0中,不再發生這種情况,因此不再需要在末尾指定ORDER BY NULL來抑制隱式排序(如前所述)。 但是,查詢結果可能與以前的MySQL版本不同。 要產生給定的排序順序,請提供ORDER BY子句

陳哈哈:“哦,這麼看來開發老版本的同事是沒用Order by,直接用了隱式排序。年輕人,不講武德啊!!”

小王(小聲):“哈哥,這模塊之前好像是你負責的。”

陳哈哈(老臉一紅):???

陳哈哈:“咳咳,這MySQL8.0團隊不講武德,給我挖坑!”

Group by隱式排序,一個優美的BUG,當上項目經理才知道_Java

好了,接下來我們用測試數據演示一下

[](

)數據測試


下面是錶T測試數據,無序


mysql> SELECT pid,appName from T;
+--------+-------------------------+
| pid | appName |
+--------+-------------------------+
| 1 | Dock Sound Redirector |
| 2 | Blues Music station |
| 3 | usb tether TRIAL |
| 4 | Il vero test del QI |
| 5 | FlightTime Calculator |
| 6 | ZX Spectrum Emulator |
| 7 | The City Dress Up |
+--------+-------------------------+
7 rows in set (0.00 sec)

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.

實驗1:(MySQL版本:5.7.24)


-- 隱式排序
mysql> SELECT pid,appName from T group by appName;
+--------+-------------------------+
| pid | appName |
+--------+-------------------------+
| 2 | Blues Music station |
| 1 | Dock Sound Redirector |
| 5 | FlightTime Calculator |
| 4 | Il vero test del QI |
| 7 | The City Dress Up |
| 3 | usb tether TRIAL |
| 6 | ZX Spectrum Emulator |
+--------+-------------------------+
7 rows in set (0.00 sec)
-- 如上述隱式排序,相當於SELECT pid,appName from T group by appName asc 或 SELECT pid,appName from T group by appName order by appName asc;
-- 顯式排序,相當於SELECT pid,appName from T group by appName order by appName desc;
mysql> SELECT pid,appName from T group by appName desc;
+--------+-------------------------+
| pid | appName |
+--------+-------------------------+
| 6 | ZX Spectrum Emulator |
| 3 | usb tether TRIAL |
| 7 | The City Dress Up |
| 4 | Il vero test del QI |
| 5 | FlightTime Calculator |
| 1 | Dock Sound Redirector |
| 2 | Blues Music station |
+--------+-------------------------+
7 rows in set (0.00 sec)

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.

實驗2:(MySQL版本:8.0.16)


mysql> SELECT pid,appName from T group by appName;
+--------+-------------------------+
| pid | appName |
+--------+-------------------------+
| 1 | Dock Sound Redirector |
| 2 | Blues Music station |
| 3 | usb tether TRIAL |
| 4 | Il vero test del QI |
| 5 | FlightTime Calculator |
| 6 | ZX Spectrum Emulator |
| 7 | The City Dress Up |
+--------+-------------------------+
7 rows in set (0.00 sec)
# 總結
機會是留給有准備的人,大家在求職之前應該要明確自己的態度,熟悉求職流程,做好充分的准備,把一些可預見的事情做好。
對於應届畢業生來說,校招更適合你們,因為絕大部分都不會有工作經驗,企業也不會有工作經驗的需求。同時,你也不需要偽造高大上的實戰經驗,以此讓自己的簡曆能够脫穎而出,反倒會讓面試官有所懷疑。
你在大學時期應該明確自己的發展方向,如果你在大一就確定你以後想成為Java工程師,那就不要花太多的時間去學習其他的技術語言,高數之類的,不如好好想著如何夯實Java基礎。下圖涵蓋了應届生乃至轉行過來的小白要學習的Java內容:
**請轉發本文支持一下**
**[CodeChina開源項目:【一線大廠Java面試題解析+核心總結學習筆記+最新講解視頻】](https://ali1024.coding.net/public/P7/Java/git)**
![Group by隱式排序,一個優美的BUG,當上項目經理才知道_後端_02](https://s3.51cto.com/images/20210919/1632023765963743.jpg)
![Group by隱式排序,一個優美的BUG,當上項目經理才知道_後端_03](https://s5.51cto.com/images/20210919/1632023765344173.jpg)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
版权声明:本文为[程序猿阿娜]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/09/20210919120923462U.html