通过SQL获取基于条件的日期列表

时间:2017-10-04 12:51:59

标签: mysql

目前在获取日期列表时遇到一些困难。

我目前有以下SQL:

SELECT DISTINCT DATE(startDate) activity_date
              , CASE WHEN (DATE(endDate) - DATE(startDate)) > 0 THEN DATE(endDate) ELSE FALSE END multiEvent 
           FROM activities 
          WHERE startdate BETWEEN '2017-08-01' AND '2017-08-31'  
            AND accountid = 578 
          ORDER 
             BY DATE(startdate)

这给出了以下结果:

activity_date | multiEvent
2017-08-07    | 0
2017-08-07    | 2017-08-10
2017-08-18    | 0

但是,我想要实现的是,如果multiEvent不为零,则列出activity_date和amp;的日期之间的日期。 multiEvent成一列。

结果我想要实现:

activity_date | 
2017-08-07    | 
2017-08-07    |
2017-08-08    |
2017-08-09    |
2017-08-10    | 
2017-08-18    | 

想法? :)

1 个答案:

答案 0 :(得分:2)

您需要先找到一种方法来为activity_datemultiEvent之间的日期创建行。此查询将生成日期的预期结果集,作为单个行。

  select date(eachDate) as eachDate from  
  (select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) as eachDate 
  from   
  (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,  
  (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,   
  (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,   
  (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,   
  (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) as v   
  where  
  eachDate between date('2017-08-07')
  and date('2017-08-10') order by eachDate asc ;

这将产生类似

的结果
eachDate
2017-08-07
2017-08-08
2017-08-09
2017-08-10

现在,我们需要在您的现有查询中使用上述查询来获取预期的输出。查询看起来像这样。

  select 
  activity_date 
  from 
  (select 
  date(startDate) as activity_date
  from
  activities 
  where 
  startdate between date('2017-08-01') and date('2017-08-31')  
  and accountid = 578 
  and NOT (DATE(endDate) - DATE(startDate)) > 0
  union all
  select 
  eachDate 
  from 
  (select date(eachDate) as eachDate 
  from  
  (select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) as eachDate  
  from   
  (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,  
  (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,   
  (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,   
  (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,   
  (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) as v   
  where  
  eachDate between date('2017-08-01')
  and date('2017-08-31')) as dates_table
  join
  (select 
  date(startDate) as startDate,
  date(endDate) as endDate
  from
  activities 
  where 
  startdate between date('2017-08-01') and date('2017-08-31')  
  and accountid = 578 
  and (date(endDate) - date(startDate)) > 0 ) as activities_table
  on dates_table.eachDate between activities_table.startDate and activities_table.endDate) as main
  order by 
  main.activity_date asc;

,输出看起来像这样。

activity_date
2017-08-07
2017-08-07
2017-08-08
2017-08-09
2017-08-10
2017-08-18