使访问者数量等于0,这在MySQL数据库中不存在

时间:2014-01-23 08:24:03

标签: php mysql sql count

我有一张桌子

___________________________________________
id |   user  | Visitor | timestamp
___________________________________________
13 |username |abc     | 2014-01-15 15:01:44
14 |username |abc     | 2014-01-15 15:01:44
15 |username |abc     | 2014-01-18 15:01:44
16 |username |abc     | 2014-01-18 15:01:44
___________________________________________

我在今天的7天内使用QUERY来计算USER abc的访问者数量。

SELECT DATE(`timestamp`) as `date`, COUNT(*) as `count`
FROM `table` WHERE (`timestamp` >= (NOW() - INTERVAL 7 DAY)) AND (`user` = 'username')
GROUP BY `date`;

得到以下输出:

______________________________
date              |  count
______________________________
2014-01-15        |     2
2014-01-18        |     2

但我需要:

______________________________
date              |  count
______________________________
2014-01-15        |     2
2014-01-16        |     0        // Make 0 for the day which is not present
2014-01-17        |     0        // Make 0 for the day which is not present
2014-01-18        |     2

将对此进行查询?

2 个答案:

答案 0 :(得分:3)

使用子查询创建一个包含过去一周所有日期的表格,然后将其与您的表格连接:

SELECT `date`, IFNULL(COUNT(*), 0) as `count`
FROM (SELECT DATE(NOW()) AS `date`
      UNION
      SELECT DATE(DATE_SUB(NOW(), INTERVAL 1 DAY))
      UNION
      SELECT DATE(DATE_SUB(NOW(), INTERVAL 2 DAY))
      UNION
      SELECT DATE(DATE_SUB(NOW(), INTERVAL 3 DAY))
      UNION
      SELECT DATE(DATE_SUB(NOW(), INTERVAL 4 DAY))
      UNION
      SELECT DATE(DATE_SUB(NOW(), INTERVAL 5 DAY))
      UNION
      SELECT DATE(DATE_SUB(NOW(), INTERVAL 6 DAY))
      UNION
      SELECT DATE(DATE_SUB(NOW(), INTERVAL 7 DAY))) AS days
LEFT JOIN `table` ON DATE(`timestamp`) = `date`
WHERE (`timestamp` >= (NOW() - INTERVAL 7 DAY)) AND (`user` = 'username')
GROUP BY `date`;

答案 1 :(得分:1)

这是关于的一个众所周知的问题 - 它在SO上有很多答案。

首先,最明显的方法是使用将连续保存所有日期的表(当前年份作为样本)例如,让它为dates表,其中包含字段record_date(它保存日期)那么你的查询将如下所示:

SELECT 
  DATE(`timestamp`) as `date`, 
  COUNT(`dates`.`id`) as `count`
FROM 
  `dates`
  LEFT JOIN
    `table`
      ON `dates`.`record_date` = DATE(`table`.`timestamp`)
WHERE 
  (`timestamp` >= (NOW() - INTERVAL 7 DAY)) 
  AND 
  (`user` = 'username')
GROUP BY 
  `dates`.`record_date`

- 你将强制通过LEFT JOIN返回零。

使用序列生成器查询实现此目的还有另一种更复杂的方法。实际上,MySQL中没有序列,但您可以从CROSS JOIN生成连续值,然后将它们应用于日期选择。例如:

SELECT
  DATE_ADD(CURDATE() - INTERVAL 1 WEEK, INTERVAL sequence.id DAY)
FROM
(SELECT
 (two_1.id + two_2.id + two_4.id + 
 two_8.id + two_16.id) AS id
 FROM
 (SELECT 0 AS id UNION ALL SELECT 1 AS id) AS two_1
 CROSS JOIN (SELECT 0 AS id UNION ALL SELECT 2 AS id) AS two_2
 CROSS JOIN (SELECT 0 AS id UNION ALL SELECT 4 AS id) AS two_4
 CROSS JOIN (SELECT 0 AS id UNION ALL SELECT 8 AS id) AS two_8
 CROSS JOIN (SELECT 0 AS id UNION ALL SELECT 16 AS id) AS two_16
 ) AS sequence
WHERE
  sequence.id<7

- 前一周会produce dates,所以你将能够使用它,而不是像第一种方式那样创建和填充临时表。关于这个查询的好处是 - 它是静态的,因此如果你想增加选择间隔,你不必添加另一个UNION部分。