Mysql SQL查找日期范围内的计数

Mysql SQL查找日期范围内的计数,mysql,sql,Mysql,Sql,我的表格如下: +--------+------------+------------+----------------+---------------+------------+ | UserID | CaseNumber | CourseName | CourseAttended | Training_Date | Created_On | +--------+------------+------------+----------------+---------------+-------

我的表格如下:

+--------+------------+------------+----------------+---------------+------------+
| UserID | CaseNumber | CourseName | CourseAttended | Training_Date | Created_On |
+--------+------------+------------+----------------+---------------+------------+
| 1      | 101        | X          | T              | 01/01/2020    | 01/12/2019 |
| 1      | 103        | X          | T              | 01/05/2020    | 01/12/2018 |
| 1      | 105        | X          | T              | 01/02/2020    | 03/03/2020 |
| 2      | 101        | X          | T              | 05/01/2020    | 03/01/2020 |
| 3      | 103        | X          | T              | 05/05/2020    | 01/01/2020 |
| 4      | 104        | X          | T              | 04/01/2020    | 01/08/2020 |
| 5      | 101        | X          | T              | 01/07/2020    | 01/02/2020 |
| 5      | 105        | X          | T              | 01/08/2020    | 01/12/2019 |
| 5      | 109        | X          | T              | 01/09/2020    | 01/10/2019 |

我想计算培训日期小于创建日期的案例数量,并计算培训日期>创建日期的案例数量。用户有多个培训日期,只考虑用户的最新培训日期。该计数应仅适用于在培训日期+-3个月后创建的案例。例如,如果创建日期为2018年,培训日期为2020年,则不应将其计算在内。仅当培训日期在+-3个月内时,才需要统计案例。

根据描述,这听起来像是一个窗口函数,用于获取最大培训日期,然后进行一些汇总:

select sum(training_date < create_date) as num_before,
       sum(training_date > create_date) as num_after       
from (select t.*,
             max(training_date) over (partition by user) as max_td
     )
where training_date = max_training_date and
      training_date >= create_date - interval 3 month and
      training_date <= create_date + interval 3 month ;
最终一次查询 根据您的描述,我通过逐步实现您的需求,提出了以下建议:

SELECT count(1)
FROM
  (SELECT d.userid,
          d.caseNumber,
          d.training_Date,
          d.created_on,
          period_diff(date_format(d.training_Date, '%Y%m'), date_format(d.created_on, '%Y%m')) AS monthsDiff
   FROM DATA d
   INNER JOIN
     (SELECT userId,
             max(training_date) AS lastTraining
      FROM DATA
      GROUP BY userid)ltu ON d.userid = ltu.userid
   AND d.training_Date = ltu.lastTraining) d
WHERE (monthsDiff >=0
       AND monthsDiff < 4)
  AND (monthsDiff <0
       AND monthsDiff > -4);
插入语句:

insert into data( userid, caseNumber, training_Date, created_on) values(                                1   ,   101 ,STR_TO_DATE('01-01-2020','%d-%c-%Y'),STR_TO_DATE('01-12-2019','%d-%c-%Y'));
insert into data( userid, caseNumber, training_Date, created_on) values(                                1   ,   103 ,STR_TO_DATE('01-05-2020','%d-%c-%Y'),STR_TO_DATE('01-12-2018','%d-%c-%Y'));
insert into data( userid, caseNumber, training_Date, created_on) values(                                1   ,   105 ,STR_TO_DATE('01-02-2020','%d-%c-%Y'),STR_TO_DATE('03-03-2020','%d-%c-%Y'));
insert into data( userid, caseNumber, training_Date, created_on) values(                                2   ,   101 ,STR_TO_DATE('05-01-2020','%d-%c-%Y'),STR_TO_DATE('03-01-2020','%d-%c-%Y'));
insert into data( userid, caseNumber, training_Date, created_on) values(                                3   ,   103 ,STR_TO_DATE('05-05-2020','%d-%c-%Y'),STR_TO_DATE('01-01-2020','%d-%c-%Y'));
insert into data( userid, caseNumber, training_Date, created_on) values(                                4   ,   104 ,STR_TO_DATE('04-01-2020','%d-%c-%Y'),STR_TO_DATE('01-08-2020','%d-%c-%Y'));
insert into data( userid, caseNumber, training_Date, created_on) values(                                5   ,   101 ,STR_TO_DATE('01-07-2020','%d-%c-%Y'),STR_TO_DATE('01-02-2020','%d-%c-%Y'));
insert into data( userid, caseNumber, training_Date, created_on) values(                                5   ,   105 ,STR_TO_DATE('01-08-2020','%d-%c-%Y'),STR_TO_DATE('01-12-2019','%d-%c-%Y'));
insert into data( userid, caseNumber, training_Date, created_on) values(                                5   ,   109 ,STR_TO_DATE('01-09-2020','%d-%c-%Y'),STR_TO_DATE('01-10-2019','%d-%c-%Y'));
仅获取最后的培训日期:

create View lastTrainingByUser as 
select userId, max(training_date) as lastTraining from data group by userid;
仅获取具有上次培训日期的案例。同时计算培训和创建之间的月差

create view lastTrainingDatesByUser as
select d.userid, d.caseNumber, d.training_Date, d.created_on,
period_diff(date_format(d.training_Date, '%Y%m'), date_format(d.created_on, '%Y%m')) as monthsDiff
from data d inner join lastTrainingByUser ltu
on d.userid = ltu.userid AND d.training_Date = ltu.lastTraining;
不带计数的查询

select d.userid, d.caseNumber, d.training_Date, d.created_on 
,d.monthsDiff
from lastTrainingDatesByUser d
where 
(monthsDiff >=0 AND monthsDiff < 4) AND
(monthsDiff <=0 AND monthsDiff > -4);
该查询包含以下计数:

select count(1)
from lastTrainingDatesByUser d
where 
(monthsDiff >=0 AND monthsDiff < 4) AND
(monthsDiff < 0 AND monthsDiff > -4);

SQLFIDLE:

使用日期数据类型存储日期。请分享你的尝试!不要简单地分享您的需求,期待我们从头开始为您提供解决方案@Shadow我创建了一个新的列来计算2 date列之间的差异,我试图只选择那些+-90的值。实际上,我必须在PowerBI中创建一个仪表板,并在其中调用一个R脚本。我正在使用sqldf包来获取查询。我没有得到正确的结果。请编辑问题并分享您尝试过的查询!另外,如果您使用的是powerbi,那么您是否需要在mysql级别而不是powerbi级别设置所有过滤器?您描述的列名是否与您显示的数据有关?您太棒了。非常感谢你。
select count(1)
from lastTrainingDatesByUser d
where 
(monthsDiff >=0 AND monthsDiff < 4) AND
(monthsDiff < 0 AND monthsDiff > -4);