私が答える必要のある質問は、「60分間にこれまでに受け取ったページリクエストの最大数はいくつですか?」です。
私はこれに似たテーブルを持っています:
date_page_requested date;
page varchar(80);
60分のタイムスライスの最大行数を探しています。
分析関数が私をそこに導くかもしれないと思ったが、今のところ私は空白を描いている。
私は正しい方向へのポインターが大好きです。
私が答える必要のある質問は、「60分間にこれまでに受け取ったページリクエストの最大数はいくつですか?」です。
私はこれに似たテーブルを持っています:
date_page_requested date;
page varchar(80);
60分のタイムスライスの最大行数を探しています。
分析関数が私をそこに導くかもしれないと思ったが、今のところ私は空白を描いている。
私は正しい方向へのポインターが大好きです。
答えには、機能するいくつかのオプションがあります。これは、結合または相関サブクエリの代わりに、 Oracleの「論理オフセットを使用したウィンドウ関数」機能を使用するオプションです。
最初にテストテーブル:
Wrote file afiedt.buf
1 create table t pctfree 0 nologging as
2 select date '2011-09-15' + level / (24 * 4) as date_page_requested
3 from dual
4* connect by level <= (24 * 4)
SQL> /
Table created.
SQL> insert into t values (to_date('2011-09-15 11:11:11', 'YYYY-MM-DD HH24:Mi:SS'));
1 row created.
SQL> commit;
Commit complete.
Tには、1日の15分ごとに1つの行が含まれ、午前11:11:11に1つの行が追加されます。クエリは3つのステップで実行されます。ステップ1は、すべての行について、その行の時刻から1時間以内に来る行の数を取得することです。
1 with x as (select date_page_requested
2 , count(*) over (order by date_page_requested
3 range between current row
4 and interval '1' hour following) as hour_count
5 from t)
次に、hour_countで順序を割り当てます。
6 , y as (select date_page_requested
7 , hour_count
8 , row_number() over (order by hour_count desc, date_page_requested asc) as rn
9 from x)
最後に、後続の行の数が最も多い最も早い行を選択します。
10 select to_char(date_page_requested, 'YYYY-MM-DD HH24:Mi:SS')
11 , hour_count
12 from y
13* where rn = 1
複数の60分のウィンドウが時間カウントで同点の場合、上記では最初のウィンドウのみが表示されます。
このようなものはどうですか?
SELECT TOP 1
ranges.date_start,
COUNT(data.page) AS Tally
FROM (SELECT DISTINCT
date_page_requested AS date_start,
DATEADD(HOUR,1,date_page_requested) AS date_end
FROM @Table) ranges
JOIN @Table data
ON data.date_page_requested >= ranges.date_start
AND data.date_page_requested < ranges.date_end
GROUP BY ranges.date_start
ORDER BY Tally DESC
これにより、必要なものが得られます。返される最初の行には、ページ数が最も多い時間が含まれている必要があります。
select number_of_pages
,hour_requested
from (select to_char(date_page_requested,'dd/mm/yyyy hh') hour_requested
,count(*) number_of_pages
from pages
group by to_char(date_page_requested,'dd/mm/yyyy hh')) p
order by number_of_pages
PostgreSQLの場合、私は最初に、分に合わせた「ウィンドウ」に対してこのようなものを最初に作成します。このためにOLAPウィンドウ関数は必要ありません。
select w.ts,
date_trunc('minute', w.ts) as hour_start,
date_trunc('minute', w.ts) + interval '1' hour as hour_end,
(select count(*)
from weblog
where ts between date_trunc('minute', w.ts) and
(date_trunc('minute', w.ts) + interval '1' hour) ) as num_pages
from weblog w
group by ts, hour_start, hour_end
order by num_pages desc
Oracleにはtrunc()関数もありますが、形式がわかりません。すぐに調べてみるか、友達のバーレスクショーを見に行きます。
WITH ranges AS
( SELECT
date_page_requested AS StartDate,
date_page_requested + (1/24) AS EndDate,
ROWNUMBER() OVER(ORDER BY date_page_requested) AS RowNo
FROM
@Table
)
SELECT
a.StartDate AS StartDate,
MAX(b.RowNo) - a.RowNo + 1 AS Tally
FROM
ranges a
JOIN
ranges b
ON a.StartDate <= b.StartDate
AND b.StartDate < a.EndDate
GROUP BY a.StartDate
, a.RowNo
ORDER BY Tally DESC
また:
WITH ranges AS
( SELECT
date_page_requested AS StartDate,
date_page_requested + (1/24) AS EndDate,
ROWNUMBER() OVER(ORDER BY date_page_requested) AS RowNo
FROM
@Table
)
SELECT
a.StartDate AS StartDate,
( SELECT MIN(b.RowNo) - a.RowNo
FROM ranges b
WHERE b.StartDate > a.EndDate
) AS Tally
FROM
ranges a
ORDER BY Tally DESC