2014-12-26 30 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可用(MySQL),請將其轉換爲CTE或創建一個視圖。

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

現在您只需檢查每週每個用戶的WeeklyCount爲4或更多。

注意:To_Char允許您按周分組。對於Oracle以外的大多數DBMS,這由DatePart函數提供。