나는 어떤 행도 생성 할 필요가 없다고 생각합니다. 샘플 데이터를 기반으로 두 테이블을 간단하게 결합 할 수 있습니다. to_char(ud.start_time, 'FMday') = lower(pi.week_day)
를 사용하여 조인
주를 반환합니다 to_char()
와 같은 언어로 저장 할 수있는 요일을 필요로
select *
from program_info pi
join usage_detail ud
on to_char(ud.start_time, 'FMday') = lower(pi.week_day)
and (pi.start_time, pi.end_time) overlaps (ud.start_time::time, ud.end_time::time)
은 (
user
는 예약 키워드이기 때문에 내가 대신
user
의
user_name
를 사용). 숫자가 아닌 문자열로 저장하는 것이 좋습니다.
그 결과 각 프로그램의 실제 시작 시간과 종료 시간을 계산할 수 있습니다. 이것은 usage_detail
에 저장된 시간 정보와 program_info
에 저장된 시간 정보를 비교하여 시작 시간 중 더 큰 시간과 종료 시간 중 작은 시간을 비교하는 복잡한 case when
문을 사용하여 수행 할 수 있습니다.
그러나 이것은 시간 범위를 사용하여 간단하게 할 수 있습니다.불행하게도, 거기에 내장 그러한 범위 시간은 없지만, 그것은 쉽게 만들 수 있습니다 :
select ud.user_name,
pi.program_id,
pi.program_category,
ud.start_time::date as start_day,
timerange(pi.start_time, pi.end_time) * timerange(ud.start_time::time, ud.end_time::time) as view_interval
from program_info pi
join usage_detail ud
on to_char(ud.start_time, 'FMday') = lower(pi.week_day)
and (pi.start_time, pi.end_time) overlaps (ud.start_time::time, ud.end_time::time)
: 실제 시작 시간과 종료 시간이 두 범위의 교차점을 사용하여 계산 될 수와
create type timerange as range (subtype = time);
*
은 범위의 경우 intersection operator입니다. 위의 반환이 :
이
with view_times as (
select ud.user_name,
pi.program_id,
pi.program_category,
ud.start_time::date as start_day,
timerange(pi.start_time, pi.end_time) * timerange(ud.start_time::time, ud.end_time::time) as view_interval
from program_info pi
join usage_detail ud
on to_char(ud.start_time, 'FMday') = lower(pi.week_day)
and (pi.start_time, pi.end_time) overlaps (ud.start_time::time, ud.end_time::time)
)
select user_name, program_id, program_category,
start_day + lower(view_interval) as actual_start_time,
extract(epoch from (upper(view_interval) - lower(view_interval))) as duration
from view_times
이 반환 :
user_name | program_id | program_category | actual_start_time | duration
----------+------------+------------------+---------------------+---------
A | 1 | News | 2016-10-31 13:15:00 | 900
A | 2 | Sports | 2016-10-31 13:30:00 | 3300
온라인을 범위로 실제 시청 시간을 갖는
user_name | program_id | program_category | start_day | view_interval
----------+------------+------------------+------------+--------------------
A | 1 | News | 2016-10-31 | [13:15:00,13:30:00)
A | 2 | Sports | 2016-10-31 | [13:30:00,14:25:00)
지금 당신이 원하는 최종 디스플레이를 가져올 수 있습니다 예 : http://rextester.com/VNXIG64065
세계에서 2016-10-31은 월요일이 아니며 일요일이 아닙니다. –
조금 나중에 깨닫고 편집 할 것입니다. 인도의 디 왈리 (Diwali) 시간, 휴가는 일요일처럼 느껴집니다. : D – KSN