【问题标题】:Getting a running total of some DISTINCT records获取一些 DISTINCT 记录的运行总计
【发布时间】:2014-01-16 15:25:24
【问题描述】:

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

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

【问题讨论】:

    标签: mysql


    【解决方案1】:

    您不需要如此复杂的联​​接来获取每个用户每天的登录次数,使用 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
    

    【讨论】:

      【解决方案2】:

      如果你想要一个累计,你为什么不这样做呢?

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

      【讨论】:

        猜你喜欢
        • 2015-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-07
        相关资源
        最近更新 更多