MySQL8.0子查詢中使用order by不生效的問題

MySQL8.0子查詢中使用order by不生效的問題

0、備忘記錄,在以後項目中遇到此類問題可以快速查閱

1、項目背景如下,獲取當天每個人員門禁通行記錄的最新一條記錄作爲出勤記錄。

2、根據需求,想到的肯定是使用sql中的GROUP BY的分組來做。
現有簡化的原始數據如下,由於id採用自增策略,我們篩選出每個人員在規定時間段內(當天)記錄的id最大的那條記錄就可以了
在這裏插入圖片描述

3、直接進行分組操作,取到的結果是每個分組id最小的一條。

SELECT
	t.id,
	t.`name`,
	t.idCard 
FROM
	campus_record t
GROUP BY t.IdCard	

在這裏插入圖片描述

4、通過對以上結果進行總結,思考如下。數據自然排序下id是由小到大,在分組中我們獲取到的數據id是組內最小的,如果我們先對數據進行倒序排序,分組中是否能獲取到最大id的記錄呢,實驗如下
通過實際操作,結果沒有達到預期結果。鬱悶中…

SELECT
	tt.* 
FROM
	( SELECT t.id, t.`name`, t.idCard FROM campus_record t ORDER BY t.id DESC) AS tt 
GROUP BY tt.idCard

在這裏插入圖片描述

5、通過一系列查詢,大概的原因是mysql自5.7進行了優化。子查詢的ORDER BY竟然在實際執行中被優化掉了。怎麼才能不被優化掉呢?加LIMIT是方案之一。
在子句中加上LIMIT之後,我們可以看到數據的整體排序是倒序的,在每個分組中也得到了預期的數據。但是LIMIT後的值該取多大呢,又是一個問題。
若被查詢的數據在可控可知的範圍內,我認爲此方案是可行的,放上1000、10000、100000也未嘗不可。若數據量完全不可控、不可知,那這種方案還是不完美

SELECT
	tt.* 
FROM
	( SELECT t.id, t.`name`, t.idCard FROM campus_record t ORDER BY t.id DESC LIMIT 1000) AS tt 
GROUP BY
	tt.idCard

在這裏插入圖片描述

6、經過以上思考,需要找到一個比較完美解決方案。
先在每個分組中使用聚合函數MAX找到最大值的id,然後再進行聯結查詢應該也可以。
經過這樣一番操作,得到了預期的結果。這種方案不受數據多少的限制。算是完美的方案了吧!!!

SELECT
	t2.id,
	t2.name,
	t2.IdCard 
FROM
	( 
		SELECT MAX( t.id ) AS "id" FROM campus_record t GROUP BY t.idCard 
	) AS t1 INNER JOIN campus_record t2 
ON t1.id = t2.id

在這裏插入圖片描述

小尾巴~~
只要有積累,就會有進步

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章