我有一个跟踪用户登录的表。我们有一个管理员仪表板等,显示了运行总计的图表。
我使用以下查询(found here)执行此操作:
SELECT t.date, @running_total := @running_total + t.count AS count
FROM (
SELECT COUNT(*) AS count, DATE(datetime) AS date
FROM user_login
WHERE datetime >= '2013-05-01'
GROUP BY date
) t
JOIN (
SELECT @running_total := t2.starting_total
FROM (
SELECT COUNT(*) as starting_total
FROM user_login
WHERE datetime < '2013-05-01'
) t2
) initialize;
user_login有一个datetime列和一个user_id。但是,现在我还被要求显示唯一用户登录的运行总数(例如:用户1在一天登录两次,用户2登录一次,即3登录,但2“唯一”)。我试着这样做:
SELECT t.date, @running_total := @running_total + t.count AS count
FROM (
SELECT COUNT(DISTINCT user_id) AS count, DATE(datetime) AS date
FROM user_login
WHERE datetime >= '2013-05-01'
GROUP BY date
) t
JOIN (
SELECT @running_total := t2.starting_total
FROM (
SELECT COUNT(DISTINCT user_id) as starting_total
FROM user_login
WHERE datetime < '2013-05-01'
) t2
) initialize;
但是它给了我不正确的结果,我假设因为在SELECT COUNT(DISTINCT user_id) AS count, DATE(datetime) AS date
选择计数和日期将其抛弃。
答案 0 :(得分:0)
您不需要这样复杂的连接来获取每个用户每天的登录次数,使用count(*)和GROUP BY将快速获得结果。
SELECT u.userid, count(*) logins_for_the_day, date(u.datetime) the_day
FROM user_login u
WHERE datetime >= '2013-05-01'
GROUP BY date(u.datetime)
ORDER BY u.user_id, datetime
答案 1 :(得分:0)
如果你想要一个总计,你为什么不这样做呢?
SELEcT date, cnt
FROM (SELECT DATE(datetime) AS date, @running_total := @running_total + count(*) as cnt
FROM user_login cross join
(select @running_total := 0) const
GROUP BY date
) ul
WHERE datetime >= '2013-05-01';
现在,您可以针对每天的唯一登录进行修改:
SELEcT date, cnt, cntu
FROM (SELECT DATE(datetime) AS date, @tot := @tot + count(*) as cnt,
@totu := @totu + count(distinct user_id) as cntu
FROM user_login cross join
(select @tot := 0, @totu := 0) const
GROUP BY date
) ul
WHERE datetime >= '2013-05-01';
注意:这给出了每天唯一登录的总和(这是您的问题似乎要求的)。我怀疑你实际上想要整体的唯一登录数量(不只是在一天之内)。为此,您需要一个额外的子查询来计算唯一身份。这是通过查看有人登录的第一天日来实现的:
SELEcT ul.date, ul.cnt, uld.cntu
FROM (SELECT DATE(datetime) AS date, @tot := @tot + count(*) as cnt
FROM user_login cross join
(select @tot := 0) const
GROUP BY date
) ul left outer join
(SELECT DATE(first_datetime) as date, @totu := @totu + count(*) as cntu
FROM (select ul.user_id, min(datetime) as first_datetime
from user_login
group by ul.user_id
) ul cross join
(select @totu := 0) const
GROUP BY DATE(first_datetime)
) uld
on uld.date = ul.date
WHERE datetime >= '2013-05-01';