我有两个表,Users
和Visitors
。在Users
中,我拥有所有用户信息,并在Visitors
中输入了登录结果。每次用户登录时,新记录都会Visitors
和user_id
进入datetime
。
我想使用上次登录的 datetime 选择所有用户。我怎么能这样做?
答案 0 :(得分:2)
为避免使用子查询计算每个用户的最近时间(这实际上意味着对n
个用户运行n
个查询),请使用group by
的mysql“技巧” 没有聚合,它返回每个组的第一行行:
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中使用 first 的last_visit值y
)在用户ID 上使用group by
,而不使用使用任何聚合函数。在其他数据库中,这将是一个错误,但是对于mysql,它返回每个组的第一个行 - 即我们想要的last_visit值(因此刚刚对行进行了排序)left join
,为从未访问过的用户提供null
值,否则会将我们想要加入的last_visit加入用户行答案 1 :(得分:1)
尝试在选择
中使用子查询例如: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;
答案 2 :(得分:0)
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