我正在尝试编写一个查询来将用户表连接到活动记录表,并为每个用户返回以下内容:
A)他们上次登录的时间。
B)过去3个月的登录次数。
这是我到目前为止所提出的:
SELECT A.UserID, COUNT( Activity ) AS Logins, MAX( TIME ) AS LastLogin
FROM UserMaster A
LEFT JOIN UserWebActivity B ON A.UserID = B.UserID
AND Activity = 'Login'
AND TIME BETWEEN DATE_SUB( NOW( ) , INTERVAL 3 MONTH ) AND NOW( )
GROUP BY A.UserID
这几乎可以使用,但它不会返回最近3个月内未登录的用户的最新登录信息。如何让count()和max()正常协同工作?
答案 0 :(得分:4)
首先分别解决每个问题:
SELECT A.UserID, MAX(TIME) AS LastLogin
FROM UserMaster A
LEFT JOIN UserWebActivity B
ON A.UserID = B.UserID
AND Activity = 'Login'
GROUP BY A.UserID
SELECT A.UserID, COUNT(Activity) AS Logins
FROM UserMaster A
LEFT JOIN UserWebActivity B ON A.UserID = B.UserID
AND Activity = 'Login'
AND TIME BETWEEN (NOW() - INTERVAL 3 MONTH) AND NOW( )
GROUP BY A.UserID
单独测试它们以确保每个查询都能按您的需要工作,并在必要时进行调整。
然后当你对他们都工作感到高兴时,将结果加在一起:
SELECT T1.UserID, T1.LastLogin, T2.Logins
FROM
(
SELECT A.UserID, MAX(TIME) AS LastLogin
FROM UserMaster A
LEFT JOIN UserWebActivity B
ON A.UserID = B.UserID
AND Activity = 'Login'
GROUP BY A.UserID
) AS T1
JOIN
(
SELECT A.UserID, COUNT(Activity) AS Logins
FROM UserMaster A
LEFT JOIN UserWebActivity B
ON A.UserID = B.UserID
AND Activity = 'Login'
AND TIME BETWEEN (NOW() - INTERVAL 3 MONTH) AND NOW()
GROUP BY A.UserID
) AS T2
ON T1.UserID = T2.UserID
这将允许MySQL充分利用不同查询的索引。
答案 1 :(得分:3)
您可以在CASE
中使用COUNT
声明:
SELECT A.UserID,
COUNT(
CASE WHEN TIME BETWEEN DATE_SUB( NOW( ) , INTERVAL 3 MONTH ) AND NOW( )
THEN Activity
END ) AS Logins,
MAX( TIME ) AS LastLogin
FROM UserMaster A
LEFT JOIN UserWebActivity B ON A.UserID = B.UserID
AND Activity = 'Login'
GROUP BY A.UserID
如果您拥有大量数据,此解决方案的效率将低于@MarkByers。
答案 2 :(得分:0)
就像一个更疯狂的想法 - 而不是MAX(TIME)
coalesce(max(time), (select max(time) from UserWebActivity where ...) )