MySql:选择按月分组的有效订阅

时间:2018-11-21 10:26:10

标签: mysql

我有以下带有订阅的MySQL-Database-Table。每个订阅都作为开始日期和结束日期。

id  | start_date | end_date
  1 | 2017-01-01 | 2017-07-01
  2 | 2017-01-15 | 2017-07-12
  3 | 2017-02-01 | 2017-08-01
  4 | 2017-03-01 | 2017-08-01
  5 | 2017-03-12 | 2017-08-12
  6 | 2017-03-30 | 2017-08-30
  7 | 2017-05-01 | 2017-11-01
  8 | 2017-06-01 | 2017-12-01
  9 | 2017-07-01 | 2018-01-01
 10 | 2017-08-01 | 2018-02-01
 11 | 2018-01-01 | 2018-07-01
 12 | 2018-02-01 | 2018-08-01
 13 | 2018-03-01 | 2018-09-01
... |        ... |        ...

我想选择每个月内所有有效的订阅。一个SQL查询可以做到吗? 我想知道:一月,二月,三月等有多少个活动订阅。 例如,仅2017年6月的查询为:

SELECT COUNT(*) FROM table 
WHERE start_date <= '2017-06-30' AND 
      end_date >= '2017-06-01'

我希望我的文字可以理解。

2 个答案:

答案 0 :(得分:1)

此方法使用日历表,其中每个月由该月的第一天表示。然后,我们只需要使用重叠范围将此日历表与当前表保持连接,即可找到每个月的订阅数。

SELECT
    c.month,
    COUNT(t.start_date) AS num_subscriptions
FROM
(
    SELECT '2017-01-01' AS month UNION ALL
    SELECT '2017-02-01' UNION ALL
    ...
    SELECT '2018-12-01'
) c
LEFT JOIN yourTable t
    ON c.month <= t.end_date AND LAST_DAY(c.month) >= t.start_date
GROUP BY
    c.month;

enter image description here

Demo

答案 1 :(得分:0)

使用功能LAST_DAY(date) FIRST_DAY(date)

LAST_DAY是有效函数,但FIRST_DAY不是有效函数。

您可以创建一个自定义函数。

DELIMITER ;;
CREATE FUNCTION FIRST_DAY(day DATE)
RETURNS DATE DETERMINISTIC
BEGIN
  RETURN ADDDATE(LAST_DAY(SUBDATE(day, INTERVAL 1 MONTH)), 1);
END;;
DELIMITER ;

从史蒂芬的答案here复制答案