場景
感覺一句話說不清,還是結合場景來說吧,如果已經對問題有了解的小夥伴直接看最後結論就可以了。
上圖是我們要做處理的數據,我們要做的是拿到每天最後一次更新的數據,也就是需要得到每天中create_date時間最大的數據。首先想到的肯定是通過group by分組,得到每天的數據。SQL語句如下:
SELECT create_date,price FROM material_price_history
WHERE del_flag = 0
AND create_date >= '2019-12-01'
AND create_date < '2019-12-06'
AND material_code_id='materialCode6'
AND type=1
GROUP BY
DATE_FORMAT(create_date, '%Y-%m-%d')
這裏很簡單,條件是12月1號到6號的數據,然後根據create_date的年月日進行分組,這樣每組數據就是每天的價格。可以看到結果如下:
這裏得到12月1號的數據並不是create_date時間最大的數據,因爲17點的時候還進行過一次數據的更新。這裏如果不進行任何處理,默認得到的是id最小的數據。
解決辦法
這裏肯定想到的是利用子查詢,即首先對數據進行排序得到臨時數據表,之後再對這個臨時表進行group by操作。
SELECT create_date,price FROM (SELECT create_date,price FROM material_price_history
WHERE del_flag = 0
AND create_date >= '2019-12-01'
AND create_date < '2019-12-06'
AND material_code_id='materialCode6'
AND type=1
ORDER BY create_date DESC) e
GROUP BY
DATE_FORMAT(create_date, '%Y-%m-%d')
得到結果如下:
我們發現結果還是沒有改變。
查閱資料後發現,在5.7版本後的mysql必須要在後面加limit纔可以得到我們想要的結果。這裏推測是高版本的sql對子查詢中的ORDER BY操作做了優化處理,導致實際上沒有進行排序。
我的mysql版本是:
但在沒有limit時,依舊無法得到正確結果。因此若結果不正確,加上limit語句後即可解決。
結論
利用子查詢,使用ORDER BY 和LIMIT語句,可以得到正確的結果。SQL語句如下:
SELECT create_date,price FROM (SELECT create_date,price FROM material_price_history
WHERE del_flag = 0
AND create_date >= '2019-12-01'
AND create_date < '2019-12-06'
AND material_code_id='materialCode6'
AND type=1
ORDER BY create_date DESC LIMIT 100000000) e
GROUP BY
DATE_FORMAT(create_date, '%Y-%m-%d')
最後得到的結果:
可以看到得到的爲創建時間17點的數據