如何根据日期返回新ID?

时间:2016-12-15 11:05:16

标签: mysql sql

我有一个包含以下数据的表(仅作为示例,实际表有600,000行)(aid =访问ID [主键]和id =用户ID [外键]):

aid  |  id  |  date
332  |  1   |  2016-12-15
331  |  4   |  2016-12-15
330  |  3   |  2016-12-15
329  |  1   |  2016-12-14
328  |  1   |  2016-12-14
327  |  2   |  2016-12-14
326  |  3   |  2016-12-13
325  |  2   |  2016-12-13
324  |  1   |  2016-12-13
323  |  1   |  2016-12-12
322  |  3   |  2016-12-12
321  |  1   |  2016-12-12

每个id都是用户主键,每次他们访问我的系统中的某些内容时,我都会在这个表中记录它们(日期格式如图所示,以及它们的id)。用户可以每天多次登录。

我希望:返回一天内访问该事物的总次数,并返回过去8天内访问该事物的新用户总数(有些事情总是如此)每天记录,所以使用“LIMIT 8”只能获得最近8天。)

我的SQL目前看起来像:

SELECT COUNT(id), COUNT(distinct id), date
FROM table
GROUP BY date
ORDER BY date DESC
LIMIT 8;

SQL正确地完成了第一部分,但我无法弄清楚如何让它返回那天从未访问过该东西的用户数。

期望的结果是,一个“newuser”代表id为“4”的用户,因为他们之前从未访问过该东西:

COUNT(id)  |  newusers  |  date
3          |  1         |  2016-12-15
3          |  0         |  2016-12-14
3          |  0         |  2016-12-13
3          |  0         |  2016-12-12

很抱歉,如果我没有说清楚这一点。

3 个答案:

答案 0 :(得分:1)

要获取新用户的数量,您需要将其与过去8天内的一组ID进行比较

我的MySQL有点生疏,所以你可能需要纠正语法。

SELECT COUNT(id) 
FROM table
WHERE id NOT IN (
    SELECT DISTINCT id
    FROM table
    WHERE date BETWEEN DATE(DATE_SUB(NOW(), INTERVAL 8 DAY)) AND DATE(DATE_SUB(NOW(), INTERVAL 1 DAY))
)

我将此作为一项任务让您将其与其他查询相结合;)

答案 1 :(得分:1)

如果数据库中的日期列是日期时间/日期或代表格式的其他日期,您可以这样做:

让所有在8天内访问过某些内容的用户:

Select id, date from table 
where date BETWEEN DATE_ADD(NOW(), INTERVAL -9 DAY) AND NOW() 

我认为,你可以做任何你想要的分组。 要获得新用户,您可以选择自我加入或使用子选择

selfjoin:

select t.id, t.date from table as t
LEFT join table as t2 
   ON t.id = t2.id 
   AND t.date BETWEEN DATE_ADD(NOW(), INTERVAL -1 DAY) AND NOW() 
   AND t2.date NOT BETWEEN DATE_ADD(NOW(), INTERVAL -9 DAY) AND NOW()
WHERE t2.id IS NULL

我使用左连接来匹配用户的所有访问权限,然后排除那些行。但是,自连接速度很慢,使用LEFT join

时速度更慢

子选择:

select id, date from table 
where date BETWEEN DATE_ADD(NOW(), INTERVAL -1 DAY) AND NOW() 
AND id NOT IN ( 
   SELECT id FROM table 
   WHERE date BETWEEN DATE_ADD(NOW(), INTERVAL -2 DAY) AND DATE_ADD(NOW(), INTERVAL -1 DAY) 
)

我知道那些带有date_adds的玩家并不是很好看,但我希望它能帮助你更多地分组日期

我建议使用日期和时间来获取更多信息,但这完全取决于您的数据含义

答案 2 :(得分:1)

要获得新用户,您希望第一天出现ID:

select id, min(date)
from t
group by id;

剩下的就是joingroup by

select d.date, cnt, count(dd.id) as newusers
from (select date, count(*) as cnt
      from t
      group by date
     ) d left join
     (select id, min(date) as mindate
      from t
      group by id   
     ) dd  
     on d.date = dd.mindate
group by d.date, d.cnt
limit 8;