获得一些DISTINCT记录的运行总计

时间:2014-01-16 15:25:25

标签: mysql

我有一个跟踪用户登录的表。我们有一个管理员仪表板等,显示了运行总计的图表。

我使用以下查询(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选择计数和日期将其抛弃。

2 个答案:

答案 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';