2014-01-06 3 views
1

У меня есть таблица подписки, которая включает в себя всю подписку на рекламу, связанную с экраном. Я хочу ограничить пользователя добавлять только 20 объявлений на экран за раз. Я сделан с количеством объявлений на экран. но проблема заключается в том, что я хочу рассмотреть диапазон дат (дату начала и дату окончания каждой подписки). Это означает, что реклама не должна превышать 20 в пределах определенного диапазона дат.count Поле таблицы mysql на основе временных интервалов

Я построил образец схемы в sqlfiddle. http://sqlfiddle.com/#!2/070cf/1

Справка будет оценена по достоинству. Благодарю.

+0

Ваш вопрос немного неточен. На какой диапазон вы пытаетесь ограничить счет? В то же время изучите предложения GROUP BY и, возможно, 'HAVING'. – Palpatim

+0

Да. Дата начала и дата окончания каждой подписки. В этом диапазоне реклама должна быть меньше 20. –

+0

Итак, вы пытаетесь создать проверку, если есть максимальное количество записей в БД для периода/пользователя перед вводом любой записи в БД? –

ответ

0

Если начало и EndDate входы для вашего оператора выбора:

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'); 
+0

Нет. Это динамично. Это уже в таблице базы данных. проверьте ссылку sqlfiddle. –

+1

Каковы ваши входы в этот запрос и каков ожидаемый результат? вы хотите проверить, превышает ли какой-либо агент этот предел? –

+0

да. Мне нужно проверить, общий подсчет подписей не более 20 в диапазоне начала и окончания даты, прежде чем какой-либо агент добавит новую подписку. –

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 кампаний в день соблюдено, andto найти обижая дней, мы присоединяемся так:

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 или более кампаний из нашего искали интервала.

Другим подходом будет проверка текущей суммы, с которой будет работать дата и время. Предположим, что подписка на таблицы с 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 
Смежные вопросы