2016-08-17 33 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; 
相关问题