2014-02-25 66 views
2

我的应用程序需要一个线图,我将显示该国家在过去3天内加入的新用户数量。我在同一个图上绘制多条线。所以,我还需要显示空值。打印零如果没有返回COUNT()

用户表:

 
+------------+-------------------+----------------------------------------+ 
|id   | First_name  |country_id  | created_at   | 
+------------+-------------------+-----------------+----------------------+ 
| 1   | AAA    | 3    | 2014-02-23 15:55:55 | 
| 2   | BBB    | 5    | 2014-02-22 15:55:55 | 
| 3   | CCC    | 1    | 2014-02-22 17:55:55 | 
| 4   | DDD    | 2    | 2014-02-22 15:55:55 | 
| 5   | EEE    | 1    | 2014-02-22 16:55:55 | 
| 6   | FFF    | 1    | 2014-02-23 15:55:55 | 
+------------+-------------------+-----------------+----------------------+ 

查询:

Select COUNT(users.id) AS count, DATE(users.created_at) AS date , users.country_id 
from `users` 
where `created_at` >= '2014-02-21' and `created_at` < '2014-02-24' and users.country_id IN(1, 3, 10) 
group by `date`, users.country_id 
order by `date` asc 

预期输出:

 
+------------+-------------------+------------------ 
|count  | date    |country_id  | 
+------------+-------------------+-----------------+ 
| 0   | 2014-02-21  | 1    | 
| 0   | 2014-02-21  | 3    | 
| 0   | 2014-02-21  | 10    | 
| 2   | 2014-02-22  | 1    | 
| 0   | 2014-02-22  | 3    | 
| 0   | 2014-02-22  | 10    | 
| 1   | 2014-02-23  | 1    | 
| 1   | 2014-02-23  | 3    | 
| 0   | 2014-02-23  | 10    | 
+------------+-------------------+-----------------+ 

上述阙如果没有数据,则不会返回任何值。如果一天中没有找到一个国家的数据,我该如何打印0。

+0

为什么你对国家ID 2和5(它们在数据中表示)的结果不感兴趣? –

+0

在预期输出你在表 –

+0

10作为COUNTRY_ID而不是'选择从那里created_at =“2014年2月21日”和COUNTRY_ID = 10'返回任何行用户*? –

回答

0

试试这个,

Select Distinct 
    (select COUNT(users.id) from `users` U where U.`date` = `date` and U.country_id = users.country_id) AS count 
    ,DATE(users.created_at) AS date , users.country_id 
from `users` 
where `created_at` >= '2014-02-21' and `created_at` < '2014-02-24' and users.country_id IN(1, 3, 10) 
group by `date`, users.country_id 
order by `date` asc 
0

试试这个:

Select 
(case when COUNT(users.ID) > 0 then COUNT(users.ID) 
else 
0 
end) as count,DATE(users.created_at) AS date , users.country_id 
from `users` 
where `created_at` >= '2014-02-21' and `created_at` < '2014-02-24' 
and users.country_id IN(1, 3, 10) 
group by `date`, users.country_id 
order by `date` asc 
+0

部分工作。但是如果国家没有可用的数据,则不打印0。 – Anam

+0

一个国家没有可用的数据是指它不存在于查询中或数据库本身?你能举个例子吗? –

0

您可以生成所有的间隔使用查询的日期。使用此查询作为嵌套查询来计数。

SELECT COUNT(users.id) AS COUNT, 
     DTTM.DATE AS date , 
     users.country_id 
FROM `users` USR, 
    (SELECT DATE 
    FROM TABLE) DTTM 
WHERE USR.created_at = DTTM.DATE 
    AND users.country_id IN(1, 3, 10) 
GROUP BY `date`, 
     users.country_id 
ORDER BY `date` ASC 

检查此链接查询来获取所有日期的范围之间。

MySQL display all date in between range

0

尝试是这样的:

Select 
case 
when (COUNT(users.id) = 0) then 0 else COUNT(users.id) end AS count, 
DATE(users.created_at) AS date , 
users.country_id 
from users 
where `created_at` >= '2014-02-21' 
and `created_at` < '2014-02-24' and users.country_id IN(1, 3) 
group by `date`, users.country_id 
order by `date` asc 
+0

不工作。与我的查询没有太大区别(不打印0)。 – Anam

0

您可能会需要生成日期列表和国家ID的列表的笛卡儿积,然后做一个左外连接与用户表中的数据进行比较并汇总结果。

SELECT COUNT(U.ID), C.Date, C.Country_ID 
    FROM (SELECT A.Country_ID, B.Date 
      FROM (SELECT 1 AS Country_ID 
       UNION 
       SELECT 3 AS Country_ID 
       UNION 
       SELECT 10 AS Country_ID 
       ) AS A 
      JOIN (SELECT '2014-02-21' AS Date 
       UNION 
       SELECT '2014-02-22' AS Date 
       UNION 
       SELECT '2014-02-23' AS Date 
       ) AS B 
      ON 1 = 1 
     ) AS C 
    LEFT JOIN Users AS U 
    ON U.Created_At BETWEEN C.Date AND DATE_ADD(C.Date, INTERVAL 1 DAY) 
    AND U.Country_ID = C.Country_ID 
GROUP BY C.Date, C.Country_ID; 

可能有更简单的方法来生成这两个列表;一般来说,你可能会用一对填充了国家ID和日期的临时表格做得最好。关键在于你拥有统治表(左外连接的LHS上的表)对于你想要的每个结果行都包含一行,然后在连接的RHS表中的实际(稀疏)数据。 COUNT(U.ID)术语计算非空值的数量;如果给定的日期和国家没有匹配,则LOJ会产生一个NULL作为用户ID,但COUNT(U.ID)会忽略那些空值,如果根本没有值,则返回0。

+0

感谢您的回答。一些语法在mysql中是未知的(例如DATEADD) – Anam

+0

Oh Futz;我错误地输入了名字,知道了我的名字,并且在检查了其他通话的语法后忘了添加下划线。当然,你知道在MySQL手册中查找日期函数的位置(如果你没有 - [找到它们]不要承认它(http://dev.mysql.com/doc/refman/5.7/en/ date-and-time-functions.html)!),并且很容易猜到DATEADD应该被拼写成DATE_ADD。 –

0

这应该是算法中:

  1. 生成指定范围内的所有日期,并做了所有国家交叉联接
  2. LEFT JOIN与日期和国家ID用户表上面的结果集
  3. 在日期和国家ID上进行分组