2017-09-07 22 views
1

30分の時間間隔でログインしたユーザーをカウントします。30分の時間間隔を持つ1日のユーザー数oracle

合計48の間隔があります。ユーザがデータベースにログインしてstart_time(ログイン)とend_time(ログアウト時間)を入力すると、ユーザIDがテーブルに記録されます ユーザは複数の期間にログインできます。私は2017-jul-12データを取っています 例: id 2のユーザーは2回ログインしていますので、そのユーザーのカウント値は2になります(12:02から12:07および11:午後4時〜午後11時51分)同様に、期間内にログインし、カウント以外の期間にログアウトした場合は、期間2の間に処理されます。 例:id 3のユーザの場合...

入力

user     start_date       end_time 
1  12-JUL-17 12.02.09.430000000 AM  12-JUL-17 12.02.13.310000000 AM 
2  12-JUL-17 12.02.13.323000000 AM  12-JUL-17 12.07.33.343000000 AM 
3  12-JUL-17 12.06.19.203000000 AM  12-JUL-17 12.37.49.890000000 AM 
4  12-JUL-17 12.07.33.357000000 AM  12-JUL-17 12.07.37.813000000 AM 
5  12-JUL-17 12.07.37.813000000 AM  12-JUL-17 12.07.40.690000000 AM 
6  12-JUL-17 12.07.40.707000000 AM  12-JUL-17 12.12.58.470000000 AM 
7  12-JUL-17 12.12.58.487000000 AM  12-JUL-17 12.13.01.937000000 AM 
8  12-JUL-17 12.13.01.950000000 AM  12-JUL-17 12.18.22.193000000 AM 
9  12-JUL-17 12.13.20.267000000 AM  12-JUL-17 12.45.38.013000000 AM 
2  12-JUL-17 11.46.17.827000000 PM  12-JUL-17 11.51.32.267000000 PM 
3  12-JUL-17 11.47.03.497000000 PM  13-JUL-17 12.20.17.167000000 AM 

出力

count(id)  interval 
    9    1 
    2    2 
    0    47 
    2    48 

合計48点の間隔(30分ごと)

count(id)  interval 
    9    1 (12 - 12:30 am) 
    2    2 (12:30 - 1:00 am) 
    .     . 
    .     . 
    .    47 (11:00 - 11:30 pm) 
    2    48 (11:30 - 12:00 am) 

クエリ

With Periods as 
(
select to_timestamp(:TheDate, 'yyyy-mm-dd hh24:mi:ss') + (level-1)/48 as p_start, to_timestamp(:TheDate, 'yyyy-mm-dd hh24:mi:ss') + (level)/48 as p_end, level as p_id 
from dual connect by level<=48 
) 
select p.*, count(distinct t1.id) as distinct_users 
from Periods p 
left join Input t1 
on t1.start_date < p_end 
and t1.end_date >= p_start 
group by p.p_id, p.p_start, p.p_end 

は、私はすでにこのクエリと遊んしかし、それは私に正確な答えを与えていない あります:両方の日付列のタイムスタンプは

です与えられる

クエリヒント:ROWNUM = 48 <は異なる間隔を表すALL_OBJECTSに対して加わるとこれにhttps://stackoverflow.com/users/2144048/johnhc

+0

正確な答えは何ですか? – wolfrevokcats

+1

このような問題で常に発生する「境界問題」についての質問。ユーザが10:00にログインし、10:30にログアウトしたとします。このユーザーは、9:30〜10:00の間、「ログインしましたか」でしたか?彼女は10時30分から11時までの間、「ログインしましたか」でしたか?そうでない場合は、可能な境界条件のそれぞれをどのように処理するかを正確に指定する必要があります。 – mathguy

+0

@wolfrevokcats感謝の気持ちを示す_wolfrevokcats感謝の言葉...私はすでにあなたが見ることができる出力を表示しました。ユーザーは48の間隔で数えたいと思っています – steve

答えて

1

私はだろう。次に、それをあなたの期間表と結合し、ユーザー別にグループ化します。

SELECT intervals.interval, COUNT(DISTINCT "USER") FROM (SELECT rownum AS interval FROM all_objects WHERE rownum <= 48) intervals 
LEFT OUTER JOIN test2 ON intervals.interval BETWEEN EXTRACT(HOUR FROM start_date) * 2 + FLOOR(EXTRACT(MINUTE FROM start_date)/30) + 1 
               AND CASE WHEN EXTRACT(DAY FROM start_date) != EXTRACT(DAY FROM end_time) THEN 48 ELSE EXTRACT(HOUR FROM end_time) * 2 + FLOOR(EXTRACT(MINUTE FROM end_time)/30) + 1 END 
GROUP BY intervals.interval 
ORDER BY intervals.interval 
+0

感謝しました!私は少しの変更を行った後 – steve

関連する問題