2016-08-17 32 views
1

(修訂版)
我有兩個表像下面獲取引起的,包括不存在日期的給定範圍內的所有日期

subscribers

id | service_id | subscribe_date 

1 | 1   | 2016-08-10 
2 | 2   | 2016-08-09 
3 | 2   | 2016-08-05 
4 | 1   | 2016-08-03 

services

id | service_name 

1 | test1   
2 | test2 
3 | test2 

subscribers.service_id有一個外鍵services.id

我想從這個表中數據如下圖所示:

service_id | subscribe_date | count 

1  | 2016-08-10  | 1 
1  | 2016-08-09  | 0 
2  | 2016-08-10  | 0 
2  | 2016-08-09  | 1 
3  | 2016-08-10  | 0 
3  | 2016-08-09  | 0 

我想用下面的查詢來獲得這樣的數據:

SELECT COUNT(*), subscribe_date, service_id 
FROM subscribers 
    INNER JOIN services ON subscribers.service_id = services.id 
WHERE subscribe_date BETWEEN '2016-08-09' AND '2016-08-10' 
GROUP BY service_id, subscribe_date; 

但我不是成功的。我得到如下的結果:

1  | 2016-08-10  | 1 
2  | 2016-08-09  | 1 
+1

請問您能解釋一下預期的輸出嗎? – 1000111

+0

輸出應顯示每個服務訂閱計數在特定日期,在哪裏導致 – Ali

+0

這是不可能的,除非你從「日曆」表獲得幫助。但是這樣做肯定會加劇代碼的美感。最好在應用程序級別做這件事。 – 1000111

回答

1

在這裏你去:

既然你沒有任何calendar表,以便我們需要通過查詢來創建您指定日期範圍內(含)之間的所有日期。但就像我說過的,在使用它之前你需要同意這個查詢的terms & conditions

SELECT 
dateWiseServices.id AS service_id, 
dateWiseServices.`Day` AS subscribed_date, 
COALESCE(yourQuery.total,0) AS cnt 

FROM 
(
    SELECT 
    S.id, 
    dateTable.Day 
    FROM 
    (
    SELECT ADDDATE('2016-08-09', INTERVAL @i:[email protected]+1 DAY) AS DAY 
    FROM (
    SELECT a.a 
    FROM (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a 
    CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b 
    CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c 
    ) a 
    JOIN (SELECT @i := -1) r1 
    WHERE 
    @i < DATEDIFF('2016-08-10', '2016-08-09') 
    ) AS dateTable 
    CROSS JOIN Services S 
) AS dateWiseServices 

LEFT JOIN 
(
    SELECT COUNT(*) AS total, subscribe_date, service_id 
    FROM subscribers 
      INNER JOIN services ON subscribers.service_id = services.id 
    WHERE subscribe_date BETWEEN '2016-08-09' AND '2016-08-10' 
    GROUP BY service_id, subscribe_date 
) AS yourQuery 
ON dateWiseServices.id = yourQuery.service_id AND dateWiseServices.`Day` = yourQuery.subscribe_date 
ORDER BY dateWiseServices.id, dateWiseServices.`Day` DESC 
+0

謝謝:) 只是爲了學習,我應該如何做到這一點,如果我有日曆表? – Ali

+0

完整答案太寬泛了! :)我會建議發佈它作爲一個單獨的問題。 – 1000111

+0

我如何聊天?這可能嗎? – Ali

0

而是內部聯接使用左加入

SELECT COUNT(*), subscribe_date, service_id 
FROM subscribers LEFT JOIN services ON subscribers.service_id = services.id 
GROUP BY service_id,subscribe_date; 
+0

OP想要添加計數爲0的行。LEFT JOIN不會幫助。 – jarlh

+0

謝謝,但它沒有幫助 – Ali

0

請試試這個,我希望這將幫助你..

SELECT service_id,subscribe_date,COUNT(service_id) 
FROM subscribers WHERE subscribe_date BETWEEN '2016-08-09' AND '2016-08-10' 
GROUP BY service_id, subscribe_date; 

如果你嘗試檢查外鍵也試試下面的查詢。

SELECT subscribers.service_id,subscribers.subscribe_date,COUNT(subscribers.service_id) 
FROM subscribers,services WHERE subscribers.service_id=services.id 
AND subscribe_date BETWEEN '2016-08-09' AND '2016-08-10' GROUP BY service_id, subscribe_date; 
相關問題