在MySQL中计算时间范围内的条目

时间:2017-05-23 18:49:02

标签: mysql

我的数据库中有一个表格,用于记录用户的持续时间 是活动的还是非活动的如果用户从活动切换到非活动或 反之亦然(或更改地址等任何其他属性)添加新记录。简化版本如下所示:

UserID       state         state_from         state_to

1            active        2016-12-14        2017-01-15
2            active        2016-12-14        2017-02-02
3            active        2017-01-01        NULL
1            inactive      2017-01-16        2017-03-05
2            inactive      2017-02-02        NULL
1            active        2017-03-06        NULL

我想计算每月有多少用户在某个时候状态“活跃”。 1月到3月所需的输出表将是:

date         user_count

2017-01      3    
2017-02      2
2017-03      2

对于特定时间戳(例如2017年1月),我使用以下查询。

SET @stamp = '2017-01';
SELECT @stamp AS date, COUNT(UserID) AS user_count
FROM se_user
WHERE (state LIKE 'active' AND @stamp BETWEEN DATE_FORMAT(state_from,'%Y-%m') AND DATE_FORMAT(state_to,'%Y-%m') )
OR (state LIKE 'active' AND DATE_FORMAT(state_from,'%Y-%m') <=  @stamp AND DATE_FORMAT(state_to,'%Y-%m') IS NULL);

我的问题是,我不知道如何在日期范围内(例如从1月到3月)这样做。有没有办法做到这一点?

示例数据库和表格

-- Set up a test database 
DROP DATABASE IF EXISTS se_toy_example;

CREATE DATABASE se_toy_example;

USE se_toy_example;

-- Create example table
DROP TABLE IF EXISTS se_user;

CREATE TABLE se_user (
    UserID INT(10),
    state VARCHAR(10),
    state_from DATE,
    state_to DATE
);
-- Populate table
INSERT INTO se_user (UserID,state,state_from,state_to)
VALUES  (1,'active','2016-12-14','2017-01-15'),
        (2,'active','2016-12-14','2017-02-02'),
        (3,'active','2017-01-01',NULL),
        (1,'inactive','2017-01-16','2017-03-05'),
        (2,'inactive','2017-02-02',NULL),
        (1,'active','2017-03-06',NULL);

1 个答案:

答案 0 :(得分:1)

您需要calendar_table来获取月份日期范围,每个月都有dt_begindt_end

因此,您对当前年度的查询将成为。

<强> SQL DEMO

SELECT c.dt_begin, count(*)
FROM calendar_table c
JOIN se_user u
  ON c.dt_begin <= COALESCE(u.state_to, curdate() ) 
 AND c.dt_end   >= u.state_from 

WHERE dt_begin >= '2017-01-01'
  AND dt_begin <= '2017-12-01'
  AND state = 'active'
GROUP BY  c.dt_begin   
  ;

<强>输出

enter image description here

注意:如果想要0活动的月份,您可以使用LEFT JOIN