如果COUNT()没有返回,则打印零

时间:2014-02-25 06:50:42

标签: mysql sql

我的应用需要一个折线图,其中我将显示过去3天内该国加入的新用户数量。我正在同一个图上绘制多条线。所以,我也需要显示空值。

用户表:

+------------+-------------------+----------------------------------------+
|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。

6 个答案:

答案 0 :(得分: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 

答案 1 :(得分: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 

答案 2 :(得分: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

答案 3 :(得分: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 

答案 4 :(得分:0)

您可能需要生成日期列表和国家/地区ID列表的笛卡尔积,然后使用users表中的数据对其进行左外连接并汇总结果。

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。

答案 5 :(得分:0)

这应该是算法:

  1. 生成指定范围内的所有日期,并与所有国家/地区进行交叉加入
  2. 将上述结果集与日期和国家/地区ID
  3. 上的用户表连接起来
  4. 对日期和国家/地区ID进行分组