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
小尾巴~~
只要有積累,就會有進步