1

Web サイトの統計データを生成するクエリを作成しようとしていますが、30 分間隔でクエリを作成する方法を見つけようとしています。

私が遭遇した別の質問に基づいて、私はこれを思いつきました:

SELECT count(*), dt FROM (
  (SELECT TO_CHAR(TRACK_DATETIME,'dd/mm/yyyy hh24') || ':' || DECODE(TRUNC(to_number(to_char(TRACK_DATETIME,'mi'))/30),0,'00','30') as DT FROM tbl_stat)
)
group by dt

これはうまく機能しますが、唯一の例外は、アクティビティのない間隔がまったく表示されないことです。すべての 30 分間隔 (空の間隔も含む) を表示する方法はありますか?

ありがとう

4

1 に答える 1

0

ここでの秘訣は、すべての間隔のリストを生成してから、テーブルへの外部結合を実行して、各間隔にあるレコードの数を確認することです。

クエリの範囲があると仮定すると(ここではvarchar2、SQL * Plusでこれを簡単に実行できるように、バインド変数を設定しています。たとえば?、JDBCの場合など、Webクライアントから別のことを実行します)。 :

var start_time varchar2(16);
var end_time varchar2(16);

exec :start_time := '12/07/2012 08:00:00';
exec :end_time := '12/07/2012 12:00:00';

select start_time + (level - 1)/48 as period_start,
    start_time + level/48 - interval '1' second as period_end
from (
    select to_date(:start_time, 'DD/MM/YYYY HH24:MI:SS') start_time,
        to_date(:end_time, 'DD/MM/YYYY HH24:MI:SS') end_time
    from dual
)
connect by start_time + (level - 1)/48 < end_time;

これにより、08:00から12:00までのすべての30分期間のリストが生成されます。

PERIOD_START        PERIOD_END
------------------- -------------------
12/07/2012 08:00:00 12/07/2012 08:29:59
12/07/2012 08:30:00 12/07/2012 08:59:59
12/07/2012 09:00:00 12/07/2012 09:29:59
12/07/2012 09:30:00 12/07/2012 09:59:59
12/07/2012 10:00:00 12/07/2012 10:29:59
12/07/2012 10:30:00 12/07/2012 10:59:59
12/07/2012 11:00:00 12/07/2012 11:29:59
12/07/2012 11:30:00 12/07/2012 11:59:59

次に、それをCTEまたはサブクエリとして使用し、実際のテーブルで一致するレコードを見つけることができます。

with tmp_tab as (
    select start_time + (level - 1)/48 as period_start,
        start_time + level/48 - interval '1' second as period_end
    from (
        select to_date(:start_time, 'DD/MM/YYYY HH24:MI:SS') start_time,
            to_date(:end_time, 'DD/MM/YYYY HH24:MI:SS') end_time
        from dual
    )
    connect by start_time + (level - 1)/48 < end_time
)
select to_char(tt.period_start, 'DD/MM/YYYY HH24:MI') dt,
    count(ts.track_datetime)
from tmp_tab tt
left join tbl_stat ts
on ts.track_datetime between tt.period_start and tt.period_end
group by tt.period_start
order by tt.period_start;

数レコードしかないダミーテーブルを使用すると、次のようになります。

DT               COUNT(TS.TRACK_DATETIME)
---------------- ------------------------
12/07/2012 08:00                        0
12/07/2012 08:30                        0
12/07/2012 09:00                        1
12/07/2012 09:30                        2
12/07/2012 10:00                        0
12/07/2012 10:30                        1
12/07/2012 11:00                        0
12/07/2012 11:30                        0
于 2012-07-12T12:23:42.933 に答える