根据时间间隔计算mysql表字段

时间:2014-01-06 16:32:09

标签: php mysql sql database

我有订阅表,其中包括与屏幕相关的所有订阅广告。我想限制用户一次只能为每个屏幕添加20个广告。我完成了每个屏幕的广告计数。但问题是,我想考虑日期范围(每个订阅的开始日期和结束日期)。这意味着广告在特定日期范围内不得超过20个。

我在sqlfiddle中构建了示例模式。 http://sqlfiddle.com/#!2/070cf/1

帮助将不胜感激。感谢。

2 个答案:

答案 0 :(得分:1)

您需要检查间隔中每天的状况。这是我强烈建议在应用程序层中执行的操作,因为mysql实际上不是为此循环而构建的。

但是为了争论,这里是如何在sql中解决它: 1.将搜索的间隔扩展到所有日期 2.检查每天的状况

第1步:扩展间隔

select *, start_date+interval nr.number day as search_date -- search date is the exploded interval
from
(select date('2013-01-13') as start_date, date('2013-02-20') as end_date) search -- the dates we search for
inner join -- joining a numbers table to expand the interval
(select a.nr+b.nr*10 as number from
    (select 1 as nr
    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
    union all select 0
    )a
    join
    (select 1 as nr
    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
    union all select 0
    )b
    order by 1 asc
) nr
on nr.number<=datediff(end_date, start_date)

现在您有列start_date,end_date,search_date,其中搜索日期包含开始和结束之间的所有日期。我们将此查询称为“date_interval”

根据您的订阅表,假设您有一个包含其他date_start和date_end的表。要计算每天不超过20个广告系列的条件是否得到满足,并找到违规日期,我们就这样加入:

select search_date, count(*) as subscriptions_active from
date_interval as di
inner join 
subscriptions as s 
on di.search_date between s.date_start and s.date_end
group by search_date
having subscriptions_active <20

从我们搜索的时间间隔生成包含20个或更多广告系列的日期表。

另一种方法是检查运行总计,这将与datetime一起使用。 假设使用start_date和end_date的表订阅,查询示例如下。现在可以很容易地检查此表中搜索的开始日期和结束日期之间是否存在不符合条件的日期时间。

select c.date, c.change_,

(select sum(change_) from   (select start_date as date, change_ from 
        (select start_date , 1 as change_ from 
                (select date('2013-01-13') as start_date, date('2013-02-20') as end_date
                union all
                select date('2013-01-14') as start_date, date('2013-04-25') as end_date
                union all
                select date('2013-03-15') as start_date, date('2013-05-25') as end_date)a
        union
        select end_date, -1 as change_ from 
                (select date('2013-01-13') as start_date, date('2013-02-20') as end_date
                union all
                select date('2013-01-14') as start_date, date('2013-04-25') as end_date
                union all
                select date('2013-03-15') as start_date, date('2013-05-12') as end_date)a
        order by 1 asc)b
    )d where d.date<=c.date) as running_total










 from

    (select start_date as date, change_ from 
        (select start_date , 1 as change_ from 
                (select date('2013-01-13') as start_date, date('2013-02-20') as end_date
                union all
                select date('2013-01-14') as start_date, date('2013-04-25') as end_date
                union all
                select date('2013-03-15') as start_date, date('2013-05-25') as end_date)a
        union
        select end_date, -1 as change_ from 
                (select date('2013-01-13') as start_date, date('2013-02-20') as end_date
                union all
                select date('2013-01-14') as start_date, date('2013-04-25') as end_date
                union all
                select date('2013-03-15') as start_date, date('2013-05-12') as end_date)a
        order by 1 asc)b
    )c

答案 1 :(得分:0)

如果开始日期和结束日期是select语句的输入:

SELECT count(screen_id) as ad_count
FROM subscription  
WHERE  
  screen_id=1 AND 
  DATE_START >= STR_TO_DATE('19,01,2014','%d,%m,%Y') and  
  DATE_END <= STR_TO_DATE('23,01,2014','%d,%m,%Y');