簡體   English   中英

第一順序......那么GROUP BY

[英]FIRST ORDER BY … THEN GROUP BY

我有兩個表,一個存儲用戶,另一個存儲用戶的電子郵件地址。

  • 表用戶:( userIdusername etc
  • table userEmail:( emailIduserIdemail

我想做一個查詢,允許我獲取最新的電子郵件地址和用戶記錄。
我基本上是在尋找一個查詢

FIRST ORDER BY userEmail.emailId DESC 
THEN GROUP BY userEmail.userId

這可以通過以下方式完成:

SELECT 
  users.userId
, users.username
, (
     SELECT 
       userEmail.email
     FROM userEmail
     WHERE userEmail.userId = users.userId
     ORDER BY userEmail.emailId DESC
     LIMIT 1
  ) AS email
FROM users
ORDER BY users.username;

但是這會為每一行做一個子查詢,效率非常低。 (在我的程序邏輯中,做兩個單獨的查詢並將它們“加入”在一起會更快。


為我想要的東西寫的直觀查詢將是:

SELECT 
  users.userId
, users.username
, userEmail.email
FROM users
LEFT JOIN userEmail USING(userId)
GROUP BY users.userId
ORDER BY 
  userEmail.emailId
, users.username;

但是,這不符合我的意願。 GROUP BY在排序之前執行,因此ORDER BY userEmail.emailId無需執行任何操作)。


所以我的問題是:
是否可以在不使用子查詢的情況下編寫第一個查詢?


我已經搜索並閱讀了有關stackoverflow的其他問題,但似乎沒有人回答有關此查詢模式的問題。

但是這會為每一行做一個子查詢,效率非常低

首先,你有一個證明這個的查詢計划/時間表嗎? 你完成它的方式(使用subselect)幾乎是“直觀”的方式。 許多DBMS(雖然我不確定MySQL)對這種情況有優化,並且只能執行一次查詢。

或者,您應該能夠創建一個僅具有ONLY (user id, latest email id)元組的子表,並JOIN到該表:

SELECT 
  users.userId
, users.username
, userEmail.email
FROM users
INNER JOIN 
      (SELECT userId, MAX(emailId) AS latestEmailId
       FROM userEmail GROUP BY userId)
      AS latestEmails
      ON (users.userId = latestEmails.userId)
INNER JOIN userEmail ON
      (latestEmails.latestEmailId = userEmail.emailId)
ORDER BY users.username;

如果這是您經常進行的查詢,我建議您優化表來處理此問題。

我建議在users表中添加emailId列。 當用戶更改其電子郵件地址或將舊電子郵件地址設置為主電子郵件地址時,請更新users表中的users行以指示當前的emailId

修改代碼以執行此更新后,您可以返回並更新舊數據以為所有用戶設置emailId

或者,您可以向users表添加email列,這樣您就不必進行聯接即可獲取用戶當前的電子郵件地址。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM