簡體   English   中英

使用LEFT JOIN,GROUP BY和ORDER BY的MySQL查詢

[英]MySQL query with LEFT JOIN, GROUP BY and ORDER BY

我有兩個表, UsersVisitors 在“ Users ,我具有所有用戶信息,在“ Visitors我輸入了登錄結果。 每次用戶登錄時,新記錄都會使用user_iddatetime進入Visitors

我想選擇所有具有上次登錄日期用戶 我怎樣才能做到這一點?

為了避免使用子查詢來計算每個用戶的最新時間(這實際上意味着對n用戶運行n查詢),請使用組的mysql“技巧” group by 聚合),它返回每個組的第一行:

select u.*, last_login
from users u
left join (select id, last_login 
  from (select u.id, v.last_login
    from users u
    join visits v on v.user_id = u.id
    order by 1, 2 desc
  ) x
group by 1) y on y.id = u.id;

該查詢的效果非常好,只需對訪問量表進行一次遍歷(9)(每個用戶都沒有子查詢)。

這是正在發生的事情的分解:

  • 最里面的查詢(別名為x )按順序獲取用戶ID和last_visit,並在每個用戶ID中首先獲取我們想要的last_visit值
  • 下一個查詢(別名為y )使用基於用戶ID的group by而不使用任何聚合函數。 在其他數據庫中,這將是一個錯誤,但是在mysql中,它返回每個組的第一行-即我們想要的last_visit值(因此對行進行了排序)
  • 最終的最外面的查詢對這些結果進行left join ,為從未訪問過的用戶提供null值,否則將我們要加入的last_visit加入用戶行

嘗試在選擇中使用子查詢

例如: select u.name,(select datetime from visitors v where u.id_user = v.id_user order by datetime desc limit 1) as lastlogin_datetme from users u;

SELECT cur.textID, cur.fromEmail, cur.subject, 
     cur.timestamp, cur.read
FROM incomingEmails cur
LEFT JOIN incomingEmails next
    on cur.fromEmail = next.fromEmail
    and cur.timestamp < next.timestamp
WHERE next.timestamp is null
and cur.toUserID = '$userID' 
ORDER BY LOWER(cur.fromEmail)

Basically, you join the table on itself, searching for later rows.

在where子句中,您聲明以后不能再有行。 這僅給您最新行。

如果可以有多個具有相同時間戳的電子郵件,則此查詢將需要優化。 如果電子郵件表中有一個增量ID列,請按以下方式更改JOIN:

LEFT JOIN incomingEmails next
    on cur.fromEmail = next.fromEmail
    and cur.id < next.id

暫無
暫無

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

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