在開發微信線上客服系統時,需要從訊息記錄表中查詢最近聯繫的用戶。表結構包含 ID、uid、content、weid、addtime 等欄位。最初嘗試使用以下 SQL:
SELECT f.*
FROM `enet_wechat_message` AS m
LEFT JOIN `enet_wechatfans` AS f ON m.fakeid = f.openid
AND m.weid = 135
AND f.weid = 135
WHERE f.fakeid IS NOT NULL
GROUP BY m.fakeid
ORDER BY m.id DESC
LIMIT 10
但結果並非預期中的「最近聯繫用戶」。
MySQL 的查詢執行順序為:FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT。這意味著 ORDER BY 在 GROUP BY 之後執行,導致分組前的排序失效,MySQL 會從每組中任意取一行(通常是第一行),而非最新的一行。
利用子查詢先按時間倒序排列,再進行分組,即可保留每組的最新記錄:
SELECT *
FROM (
SELECT *
FROM `enet_wechat_message`
WHERE weid = 135
ORDER BY `id` DESC
) `temp`
GROUP BY fakeid
ORDER BY `id` DESC
LIMIT 10
結合用戶資訊表的最終查詢:
SELECT f.*
FROM (
SELECT *
FROM (
SELECT *
FROM `enet_wechat_message`
WHERE weid = 135
ORDER BY `id` DESC
) `temp`
GROUP BY fakeid
ORDER BY `id` DESC
LIMIT 10
) AS m
LEFT JOIN `enet_wechatfans` AS f ON m.fakeid = f.openid
WHERE f.fakeid IS NOT NULL
GROUP BY m.fakeid
ORDER BY m.id DESC