私はあなたが行を生成する必要はないと思う。サンプルデータに基づいて、2つのテーブルを単純に結合することができます。
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)
to_char(ud.start_time, 'FMday') = lower(pi.week_day)
を使用して参加がto_char()
がそれを返すであろうと同じ言語で格納される曜日を必要とすること
注(user
は予約キーワードであるので、私は、user_name
代わりにuser
を使用)。文字列ではなく数値として格納する方がよいでしょう。
その結果、各プログラムの実際の開始時刻と終了時刻を計算することができます。これは、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です。上記戻り、この:範囲は、今あなたが望む最終的な表示を取得するために使用することができるよう
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)
は、実際の視聴時間を持つ:
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
オンライン例:http://rextester.com/VNXIG64065
私の世界では、2016-10-31は月曜日ではなく日曜日です。 –
少し後でそれを認識して編集します。インドのディワリ時間、休暇は日曜日のように感じられます。 :D – KSN