最近有個需求,要一些資料 Group 起來,不過後來測試發現會有欄位資料拿錯的情況,趕緊去請教公司的 DBA 大神之後,發現是我的 SQL 下錯了。
假設有一批水果資料,攤平之後是這樣:
sn item attr1 attr2 attr3 created_date 1 蕃茄 1 2 3 2015-01-15 2 蘋果 1 1 1 2015-01-27 3 蘋果 2 3 4 2015-01-28 4 蘋果 3 3 3 2015-01-29 5 香蕉 1 1 1 2015-01-27 6 香蕉 2 2 2 2015-01-28 7 橘子 1 1 1 2015-01-28 9 蘋果 5 4 0 2015-01-25 11 蘋果 3 2 3 2015-01-20
我想要拿出每種水果最新一筆的資料,所以使用以下語法:
1 2 3 4 5 6 7 |
SELECT sn, item, attr1, attr2, attr3, MAX(created_date) AS created_date FROM fruits GROUP BY item HAVING created_date <= '2015-01-30' ORDER BY created_date |
created_date 欄位型態是時間,所以可以直接用 MAX 運算。
sn item attr1 attr2 attr3 created_date 1 蕃茄 1 2 3 2015-01-15 5 香蕉 1 1 1 2015-01-28 7 橘子 1 1 1 2015-01-28 11 蘋果 3 2 3 2015-01-29
但拿出來之後,檢查發現「香蕉」欄位除了日期以外,其他資料都錯了,而「蘋果」的 serial 和 attr2 兩個欄位也錯了,實際上資料庫並沒有照我預期的方式給我資料。
後來請教 DBA 大神之後,發現我語法應該改成這樣:
1 2 3 4 5 6 7 8 9 |
SELECT * FROM fruits WHERE ( item , created_date ) IN ( SELECT item, MAX(created_date) AS created_date FROM fruits GROUP BY item HAVING created_date <= '2015-01-30' ) ORDER BY created_date |
先用 sub query 拿出我要的條件,然後用 WHERE IN 再去把資料撈出來
sn item attr1 attr2 attr3 created_date 1 蕃茄 1 2 3 2015-01-15 6 香蕉 2 2 2 2015-01-28 7 橘子 1 1 1 2015-01-28 4 蘋果 3 3 3 2015-01-29
這次就對了。