2014-12-26 1 views
0

У меня есть таблица использования сервиса по идентификатору пользователя, которая сопровождается таблицей измерений, включая дату, день недели, час дня и т. Д. Каждый раз, когда пользователь использует эту услугу, создается новая строка, которая регистрирует время использования.Проверка журналов служб для пользователей «рабочего времени» - условия в наличии предложения

Я хочу найти пользователей, которые используют услугу, по крайней мере, четыре из пяти будних дней, каждый день регистрируя использование, по крайней мере, в 8 отдельных часов дня. Это пользователи рабочего времени. Как я могу это достичь?

В настоящее время я вступаю в компромисс с приведенным ниже пунктом having, который полностью не фиксирует указанные выше условия. Скорее, он получает пользователей, которые используют эту услугу, по крайней мере, в течение 16 рабочих дней в месяц с использованием в среднем не менее 8 часов в день.

select 
a.userId 
from SERVICE_LOGS_MTHLY a 
inner join DIM_TIME_OF_DAY b 
    on a.TOD_ID = b.TOD_ID 
having 
    count(distinct (case when b.day_of_week in ('MONDAY','TUESDAY','WEDNESDAY','THURSDAY','FRIDAY') then a.day end)) >= 16 
    AND 
    count(distinct (case when b.day_of_week in ('MONDAY') then a.day||b.hour24 end)) >= 8*count(distinct (case when b.day_of_week in ('MONDAY') then a.day end)) 
    AND 
    count(distinct (case when b.day_of_week in ('TUESDAY') then a.day||b.hour24 end)) >= 8*count(distinct (case when b.day_of_week in ('TUESDAY') then a.day end)) 
    AND 
    count(distinct (case when b.day_of_week in ('WEDNESDAY') then a.day||b.hour24 end)) >= 8*count(distinct (case when b.day_of_week in ('WEDNESDAY') then a.day end)) 
    AND 
    count(distinct (case when b.day_of_week in ('THURSDAY') then a.day||b.hour24 end)) >= 8*count(distinct (case when b.day_of_week in ('THURSDAY') then a.day end)) 
    AND 
    count(distinct (case when b.day_of_week in ('FRIDAY') then a.day||b.hour24 end)) >= 8*count(distinct (case when b.day_of_week in ('FRIDAY') then a.day end)) 

ответ

0

Это включает в себя объединение агрегата, то есть оно включает в себя два этапа. Один из них заключается в том, чтобы указать, сколько часов каждый день пользователь регистрирует услугу, а другой - для обеспечения количества будних дней каждую неделю.

Использование простой таблицы с названием Hourly, которая, как представляется, соответствует минимальному описанию вашей таблицы, см. Мой SQL Fiddle сценарий.

Первый шаг - суммирование часов в день.

select h.ID, h.StartDate, count(*) as DailyCount 
from Hourly h 
where DoW in('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday') 
group by h.ID, h.StartDate; 

Вы были не слишком ясно, так что это не предполагает одну запись в течение часа использования независимо от того, сколько раз в тот час, пользователь выполняет loggable событие. При необходимости отрегулируйте.

Теперь просто добавьте каждую неделю, сколько 8 или более дней. Это использует результаты запроса выше, поэтому сделайте это в CTE или создайте представление из него, если у вас нет доступных CTE (MySQL).

with 
Daily(ID, StartDate, DailyCount)as(
    select h.ID, h.StartDate, count(*) as DailyCount 
    from Hourly h 
    where DoW in('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday') 
    group by h.ID, h.StartDate 
) 
select d.ID, Sum(case when DailyCount < 8 then 0 else 1 end) as WeeklyCount 
from Daily d 
group by d.ID, To_Char(d.StartDate, 'iw'); 

Теперь вы просто проверяете неделю недели на 4 или больше для каждого пользователя за каждую неделю.

Примечание: To_Char позволяет вам группировать по неделям. Для большинства СУБД, отличных от Oracle, это обеспечивается функцией DatePart.