根据给定的时间戳获取每天的总数

时间:2015-08-28 11:13:03

标签: mysql

我有一张简单的表格:

user   | timestamp
===================
Foo    | 1440358805
Bar    | 1440558805
BarFoo | 1440559805
FooBar | 1440758805

我想获得每天总用户数的观点:

date       | total
===================
...
2015-08-23 | 1    //Foo
2015-08-24 | 1    
2015-08-25 | 1    
2015-08-26 | 3    //+Bar +BarFoo
2015-08-27 | 3    
2015-08-28 | 4    //+FooBar
...

我目前拥有的是

SELECT From_unixtime(a.timestamp, '%Y-%m-%d')        AS date, 
       Count(From_unixtime(a.timestamp, '%Y-%m-%d')) AS total
FROM   thetable AS a
GROUP  BY From_unixtime(a.timestamp, '%Y-%m-%d')
ORDER  BY a.timestamp ASC

仅计算某一天的用户:

date       | total
===================
2015-08-23 | 1    //Foo
2015-08-26 | 2    //Bar +BarFoo
2015-08-28 | 1    //FooBar

我准备了sqlfiddle

修改

@ splash58的解决方案返回此结果:

date       | @t:=coalesce(total, @t)
==================================
2015-08-23 | 1
2015-08-26 | 3
2015-08-28 | 4
2015-08-21 | 4
2015-08-22 | 4
2015-08-24 | 4
2015-08-25 | 4
2015-08-27 | 4
2015-08-29 | 4
2015-08-30 | 4

3 个答案:

答案 0 :(得分:2)

您可以使用变量获取累积值:

SELECT date, total, (@cume := @cume + total) as cume_total
FROM (SELECT From_unixtime(a.timestamp, '%Y-%m-%d') as date, Count(*) AS total
      FROM thetable AS a
      GROUP BY From_unixtime(a.timestamp, '%Y-%m-%d')
     ) a CROSS JOIN
     (SELECT @cume := 0) params
 ORDER BY date;

这将为您提供数据中的日期。如果您想要其他日期(没有用户开始),那么一种方法是日历表:

SELECT c.date, a.total, (@cume := @cume + coalesce(a.total, 0)) as cume_total
FROM Calendar c JOIN
     (SELECT From_unixtime(a.timestamp, '%Y-%m-%d') as date, Count(*) AS total
      FROM thetable AS a
      GROUP BY From_unixtime(a.timestamp, '%Y-%m-%d')
     ) a
     ON a.date = c.date CROSS JOIN
     (SELECT @cume := 0) params
 WHERE c.date BETWEEN '2015-08-23' AND '2015-08-28'
 ORDER BY c.date;

如果您没有日历表,也可以在查询中明确地显示日期(使用子查询)。

答案 1 :(得分:1)

您可以使用功能

TIMESTAMPDIFF(DAY,`timestamp_field`, CURDATE())

您不必将时间戳转换为其他字段dype。

答案 2 :(得分:1)

drop table if exists thetable;
create table thetable (user text, timestamp int);
insert into thetable values
('Foo', 1440358805),
('Bar', 1440558805),
('BarFoo', 1440559805),
('FooBar', 1440758805);

DROP PROCEDURE IF EXISTS insertTEMP;
DELIMITER // 
CREATE PROCEDURE insertTEMP (first date, last date) begin 
drop table if exists Calendar;
CREATE TEMPORARY TABLE Calendar (date date);
WHILE first <= last DO
INSERT INTO Calendar  Values (first);
SET first = first + interval 1 day; 
END WHILE;
END // 
DELIMITER ;

call insertTEMP('2015-08-23', '2015-08-28');

select Calendar.date, @t:=coalesce(total, @t) 
    from Calendar 
         left join 
         (select date, max(total) total 
             from (select From_unixtime(a.timestamp, '%Y-%m-%d') AS date,
                          @n:=@n+1 AS total
                       from thetable AS a, (select @n:=0) n
                    order by a.timestamp ASC) t1
                    group by date ) t2 
         on Calendar.date= t2.date, 
         (select @t:=0) t

结果

date,       @t:=coalesce(total, @t)
2015-08-23  1
2015-08-24  1
2015-08-25  1
2015-08-26  3
2015-08-27  3
2015-08-28  4