2014-02-25 96 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上進行分組