1. 程式人生 > >mysql分組取最近時間

mysql分組取最近時間

這是上午的那個問題---商品上架資訊取供應商最後(最近)釋出的價格,避免商品重複

建立表



sql查詢步驟(入坑過程)

group by分組後,MAX()函式可以作用於數字型別或者能夠轉化為數字的varchar(自己總結),當其用於datetime型別時就出很奇怪的問題了。如下

sql: 


SELECT id,accountId,mark,MAX(createTime),price FROM `accountMark` GROUP BY accountId;

結果:


結果完全亂了

然後用下面的sql:先查詢出所有資料並根據createTime排序,得到一個臨時表。然後在這個臨時表中查詢資料,通過accountId分組,createTime排序就行了


sql:


SELECT *,COUNT(accountId) as Num FROM (SELECT * FROM accountMark ORDER BY createTime desc) `temp` GROUP BY accountId ORDER BY createTime desc


子查詢結果:


但是整個sql執行又不行了
這回幾乎要崩潰了...抓狂

萬萬沒想到


下面的sql


select * from accountMark as b where not exists(select 1 from accountMark where accountId= b.accountId
and b.createTime<createTime ) 


執行結果:


結合上面的子查詢可以發現完全正確
成功解決!


整個過程從查各種資料到慢慢實踐操作花了差不多一個下午...


後來參考大神的部落格發現還有其他方法

sql如下:
SELECT
id,
accountId,
mark,
createTime,
price
FROM
accountmark t
WHERE
(
createTime = (
SELECT
MAX(createTime)
FROM
accountmark
WHERE
accountId = t.accountId
)
)
執行結果完全一樣,太讚了[/強]




筆記


不相關子查詢:子查詢的查詢條件不依賴於父查詢的稱為不相關子查詢。


相關子查詢:子查詢的查詢條件依賴於外層父查詢的某個屬性值的稱為相關子查詢,帶EXISTS 的子查詢就是相關子查詢


EXISTS表示存在量詞:帶有EXISTS的子查詢不返回任何記錄的資料,只返回邏輯值“True”或“False”


相關子查詢執行過程:先在外層查詢中取“學生表(這裡是accountMark)”的第一行記錄,用該記錄的相關的屬性值(在內層WHERE子句中給定的)處理內層查詢,若外層的WHERE子句返回“TRUE”值,則這條記錄放入結果表中。然後再取下一行記錄;重複上述過程直到外層表的記錄全部遍歷一次為止。


EXISTS語句不關心子查詢的具體內容,因此用“SELECT *”,“Exists + 子查詢”用來判斷該子查詢是否返回記錄。


Exists:若子查詢的結果集非空時,返回“True”;若子查詢的結果集為空時,返回“False” 。
NOT EXISTS :若子查詢結果為空,返回“TRUE”值;若子查詢的結果集非空時,返回 “FALSE。

distinct和group by得不到相關結果

group by 必須放在 order by 和 limit之前,不然會報錯
mysql有 group_concat函式,4.1以後才支援(以後碰到可以使用,這次groupby已解決)


因為distinct關鍵字需要對結果集進行去重,如果天然無重複,是不需要加上去重關鍵字的,若結果集有將近百萬,去重欄位又多,在tmp_table_size以及sort_buffer_size中排序已經不夠用,所以將結果集複製到磁碟,嚴重影響速度
order by m,n  不要輕易寫這種語句,一般的order by前面的m才是order by的重點,後面的n為配角,如果沒有必要,儘量去掉

參考連線1參考連線2