检查“工作时间”用户的服务日志 - 有条款的条件

时间:2014-12-26 06:38:58

标签: mysql sql plsql plsqldeveloper

我有一个用户ID的服务使用表,其中包含一个维度表,包括日期,星期几,一天中的小时等。每次用户使用该服务时,都会创建一个新的日志行使用时间。

我希望找到使用该服务的用户至少五个工作日中的四个,每天至少在一天中的8个小时内记录使用情况。这些是"工作时间"用户。我怎样才能最好地实现这个目标?

目前,我正在与下面的having条款妥协,因为它没有完全捕获上面指定的条件。相反,它使用户在一个月内至少使用该服务16个工作日,每天至少使用平均

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))

1 个答案:

答案 0 :(得分: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;

你不是太清楚所以这假定一个小时使用一个条目,无论用户执行可记录事件的那个小时多少次。必要时进行调整。

现在只需每周累计8天或更长时间。这使用上面查询的结果,如果你没有CTE可用,那么把它变成CTE或者从中创建一个视图。(/ p>

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或更多的WeeklyCount。

注意:To_Char允许您按周分组。对于除Oracle之外的大多数DBMS,这由DatePart函数提供。