分析ビュー(Analytic View)を使ったAPEXアプリケーションを作ってみます。APEXアプリケーションの作成に使用するスキーマ定義やデータの準備は、LiveSQL.oracle.com のAnalytic View Demo を元にしています。
分析ビューについては、オラクルのドキュメントを参照しています。
データ・ウェアハウス・ガイド 19c 第Ⅴ部 分析ビュー
作業にはAlways FreeのAutonomous Databaseを使用します。APEXのワークスペースおよびワークスペース・スキーマとして、APEXDEV が作成済みであることを前提とします。違う名前のスキーマの場合は、APEXDEVとなっている部分を置き換える必要があります。ただし、スキーマ名を参照するのはGRANT文くらいで、それほど多くはありません。
権限の割り当て
Autonomous Databaseの管理者ADMIN にてデータベース・アクション に接続し、SQL の画面を開きます。以下のGRANT文を実行し、APEXワークスペースで分析ビューを作成するために必要な権限を与えます。
grant create attribute dimension to <ワークスペース・スキーマ>;
grant create hierarchy to <ワークスペース・スキーマ>;
grant create analytic view to <ワークスペース・スキーマ>;
今回の作業で使用するワークスペース・スキーマはAPEXDEV なので、実行するコマンドは以下になります。
grant create attribute dimension to apexdev;
grant create hierarchy to apexdev;
grant create analytic view to apexdev;
分析ビューの作成に必要な権限が、APEXのワークスペース・スキーマに割り与えられました。
データの準備
分析ビューを作るためのデータを準備します。
2つの属性ディメンジョン(Attribute Dimension) を作成します。一つ目の属性ディメンジョンは、マネージャーの階層(Hierarchy) を持つようにします。そのために、サンプル・データセットに含まれる表EMPを使用します。もう一つの属性ディメンジョンは、日付の階層を持つようにします。表EMPに含まれる従業員が、特定の日付に売り上げた金額を記録した表を、ファクト表として作成します。
属性ディメンジョンAVT_EMP_DIMの作成
マネージャーの階層を持つ属性ディメンジョンAVT_EMP_DIM を作成します。
最初にSQLワークショップ のユーティリティ よりサンプル・データセット を呼び出し、EMP / DEPT をインストール します。
インストール をクリックするとダイアログが開きます。日本語のデータが用意されているので、言語 としてJapanese を選びます。スキーマ はデフォルト のまま変更せず、次 へ進みます。
確認画面に移ります。データセットのインストール をクリックします。表EMP、DEPTおよびビューEMP_DEPT_Vが作成されます。今回の作業で使用するのは表EMP のみです。
データセットが正常にインストールされたことを確認し、終了 をクリックします。この時点ではアプリケーションは作成しません。
データセットがインストール済みになると、アクション のボタンのラベルが更新 に変わります。
属性ディメンジョンに使われる表AVT_EMPLOYEES を作成します。表EMPにはマネージャーを保持する列MGRが定義されていますが、表AVT_EMPLOYEESには、従業員の上司(列LVL3_MGR )、その上の上司(列LVL2_MGR )、さらにその上の上司(列LVL1_MGR)と、3つの階層を列として追加しています。
SQLワークショップ のSQLコマンド にて、以下のSQLを実行します。
create table avt_employees
as
select
rownum row_wid
, v. empno
, v. ename
, coalesce ( v. lvl1_mgr, v. ename) lvl1_mgr
, coalesce ( v. lvl2_mgr, v. lvl1_mgr, v. ename) lvl2_mgr
, coalesce ( v. lvl3_mgr, v. lvl2_mgr, lvl1_mgr, v. ename) lvl3_mgr
from
(
select
e. empno
, e. ename
, trim ( '|' from regexp_substr ( sys_connect_by_path ( e. ename, '|' ), '\|[^\|]+' , 1 , 1 )) lvl1_mgr
, trim ( '|' from regexp_substr ( sys_connect_by_path ( e. ename, '|' ), '\|[^\|]+' , 1 , 2 )) lvl2_mgr
, trim ( '|' from regexp_substr ( sys_connect_by_path ( e. ename, '|' ), '\|[^\|]+' , 1 , 3 )) lvl3_mgr
from emp e
start with e. mgr is null
connect by prior e. empno = e. mgr
) v
;
作成された表AVT_EMPLOYEESの内容を確認してみます。以下のSELECT文を実行します。
select * from avt_employees; 全部で14名の従業員が検索されます。列LVL1_MGRは社長なので、すべての従業員で同じ人になります。ほとんどの従業員は2階層上の上司が社長で(12人)で、LVL3_MGRが自分自身つまりENAMEと同じになります。2人だけ3階層あり、LVL3_MGRとENAMEが異なっています。
個々の従業員を特定するのは主キーである列EMPNOがあれば十分ですが、列ROW_WID が追加されています。これはファクト表のデータを自動生成する際に、EMPNOの代わりに1から14の数を割り当てていて、その列と関連付けるために追加されています。
create or replace attribute dimension avt_emp_dim
using avt_employees
attributes (
row_wid
, empno
, lvl1_mgr
, lvl2_mgr
, lvl3_mgr
)
level emp key row_wid member name to_char ( empno) order by empno determines ( lvl3_mgr)
level lvl3_mgr key lvl3_mgr member name lvl3_mgr order by lvl3_mgr determines ( lvl2_mgr)
level lvl2_mgr key lvl2_mgr member name lvl2_mgr order by lvl2_mgr determines ( lvl1_mgr)
level lvl1_mgr key lvl1_mgr member name lvl1_mgr order by lvl1_mgr
all member name 'Total'
;
create hierarchy avt_employee_hier
using avt_emp_dim (
emp child of
lvl3_mgr child of
lvl2_mgr child of
lvl1_mgr
);
以上で属性ディメンジョンAVT_EMP_DIM に関する設定は完了です。
属性ディメンジョンAVT_DATE_DIMの作成
日付の属性ディメンジョンAVT_DATE_DIM を作成します。
属性ディメンジョンAVT_DATE_DIMに使われる表AVT_CALENDAR を作成します。以下のSQLを実行します。
実行した時点での年の1月1日から12月31日までの行が作成され、それぞれの日付に週、月、四半期、年の情報が列として定義されます。
create table avt_calendar
as
select
to_char ( v. day_dt, 'YYYYMMDD' ) row_wid -- 日
, to_char ( v. day_dt, 'IW' ) week_num -- 週
, to_char ( v. day_dt, 'MM' ) month_name -- 月
, to_char ( v. day_dt, 'Q' ) qtr_name -- 四半期
, to_char ( v. day_dt, 'YYYY' ) year_name -- 年
from
(
/*
* 2022年だと2022-01-01から2022-12-31までを日付として生成する。
* levelは 1 から 365 が与えられる。
*/
select trunc ( sysdate , 'YYYY' ) + level - 1 day_dt
from dual
/*
* trunc(sysdate,'YYYY')は実行時の西暦なので、
* add_months(trunc(sysdate,'YYYY'),12) - trunc(sysdate,'YYYY')
* は、その時の日数。つまり 1から365(閏年は366)までがLEVELに代入される。
*/
connect by level <= add_months ( trunc ( sysdate , 'YYYY' ), 12 ) - trunc ( sysdate , 'YYYY' )
) v
作成された表AVT_CALENDAR の内容を確認してみます。以下のSELECT文を実行します。
select * from avt_calendar;
列ROW_WID として日付、列MONTH_NAME として月、列QTR_NAME に四半期、列YEAR_NAME に年の情報が含まれています。列WEEK_NUMには年間で第何週にあたるか記載されていますが、これは階層には含めません。列YEAR_NAMEは実行時の年(今回は2022のみ)に限られています。
この表を使って属性ディメンジョンAVT_DATE _DIM を作成します。以下のSQLを実行します。
create or replace attribute dimension avt_date_dim
using avt_calendar
attributes (
year_name
, qtr_name
, month_name
, row_wid
)
level cal_day key row_wid member name row_wid order by row_wid determines ( month_name)
level cal_month key month_name member name month_name order by month_name determines ( qtr_name)
level cal_qtr key qtr_name member name qtr_name order by qtr_name determines ( year_name)
level cal_year key year_name member name year_name order by year_name
all member name 'Total'
;
属性ディメンジョンAVT_DATE_DIMに階層
AVT_CALENDAR_HIER を作成します。以下のSQLを実行します。
create hierarchy avt_calendar_hier
using avt_date_dim (
cal_day child of
cal_month child of
cal_qtr child of
cal_year
);
以上で属性ディメンジョンAVT_DATE_DIM に関する設定は完了です。
ファクト表AVT_EMP_SALESの作成
ファクト表AVT_EMP_SALES を作成します。以下のSQLを実行します。全体で99,999行のデータが生成されます。
create table avt_emp_sales
as
select
to_char ( trunc ( sysdate , 'YYYY' ) +round ( dbms_random. value ( 0 , 364 )), 'YYYYMMDD' ) date_wid
, round ( dbms_random. value ( 1 ,( select count ( *) from emp))) emp_wid
, round ( dbms_random. value ( 1 , 1000 ), 2 ) amount
from dual
connect by level < 100000
;
表AVT_EMP_SALESの内容を確認します。以下のSELECT文を実行します。
select * from avt_emp_sales;
列DATE_WID は表AVT_CALENDAR の列ROW_WID 、列EMP_WID は表AVT_EMPLOYEES の列ROW_WID に対応します。これらの列は、表をジョインする際に使用されます。
分析ビューAVT_EMP_SALES_AVの作成
create or replace analytic view avt_emp_sales_av
using avt_emp_sales
dimension by (
avt_date_dim
key date_wid references row_wid hierarchies ( avt_calendar_hier default )
, avt_emp_dim
key emp_wid references row_wid hierarchies ( avt_employee_hier default )
)
measures (
amount fact amount
, avg_amount fact amount aggregate by avg
, cnt_amount fact amount aggregate by count
, min_amount fact amount aggregate by min
, max_amount fact amount aggregate by max
);
ファクト表としてAVT_SALES_EMP (USING で指定)を指定しています。ディメンジョン(DIMENSION BY で指定)にAVT_DATE_DIM およびAVT_EMP_DIM 、それぞれの階層としてAVT_CALENDAR_HIER 、AVT_EMPLOYEE_HIER を指定しています。
集計結果として(MEASURES で指定)、AMOUNT (AGGREGATE BYが未指定の場合は合計 - SUM関数の適用)、AVG_AMOUNT (平均 - AVG関数の適用)、CNT_AMOUNT (件数 - COUNT関数の適用)、MIN_AMOUNT (最小値 - MIN関数の適用)、MAX_AMOUNT (最大値 - MAX関数の適用)を定義しています。
SELECT文を実行して、作成した分析ビューを確認します。以下のSELECT文を実行します。
select avt_calendar_hier. member_name, amount
from avt_emp_sales_av hierarchies ( avt_calendar_hier)
where avt_calendar_hier. level_name = 'CAL_MONTH'
order by avt_calendar_hier. member_name asc ;
avt_calendar_hier.level_name としてCAL_MONTH を指定することにより、月単位の集計結果を求めています。列AMOUNT として、月単位で集計(合計)された結果がリストされます。
以上で、分析ビューAVT_EMP_SALES_AVの作成は完了です。
分析ビューを使ったAPEXアプリケーションの作成
アプリケーション作成ウィザード を起動し、名前 を分析ビュー とします。他は設定せずアプリケーションの作成 をクリックして、空のアプリケーションを作成します。
アプリケーションが作成されたら、ホーム ・ページをページ・デザイナ で開きます。
ホーム・ページのContent Body 上でコンテキスト・メニュー を開き、リージョンの作成 を実行します。
作成されたリージョンの識別 のタイトル は売上 、タイプ として対話モード・レポート を選択します。ソース の位置 はローカル・データベース 、タイプ としてSQL問合せ を選択し、SQL問合せ として以下を記述します。
select
/* 日付ディメンジョンの情報 */
avt_calendar_hier. is_leaf cal_is_leaf
, avt_calendar_hier. member_name cal_member_name
, avt_calendar_hier. member_unique_name cal_member_unique_name
, avt_calendar_hier. parent_unique_name cal_parent_unique_name
, avt_calendar_hier. parent_level_name cal_parent_level_name
, avt_calendar_hier. depth cal_depth
/* 従業員ディメンジョンの情報 */
, avt_employee_hier. is_leaf emp_is_leaf
, avt_employee_hier. member_name emp_member_name
, avt_employee_hier. member_unique_name emp_member_unique_name
, avt_employee_hier. parent_unique_name emp_parent_unique_name
, avt_employee_hier. parent_level_name emp_parent_level_name
, avt_employee_hier. depth emp_depth
/* 各種メジャー */
, amount
, round ( avg_amount, 0 ) avg_amount
, cnt_amount
, min_amount
, max_amount
from avt_emp_sales_av
hierarchies ( avt_calendar_hier, avt_employee_hier)
where
/* 全行を集計する - 結果は1行 */
avt_calendar_hier. level_name = 'ALL'
and
avt_employee_hier. level_name = 'ALL'
上記のSELECT文は、ファクト表の全ての行を集計した結果を1行で表示します。
作成したページを実行し、対話モード・レポートの表示を確認します。
ページ・デザイナに戻り、集計結果をドリルダウンするために使用するページ・アイテムを作成します。
日付ディメンジョンのドリルダウンに使用するページ・アイテムとしてP1_CAL_DEPTH 、P1_CAL_PARENT_UNIQUE_NAME 、マネージャー・ディメンジョンのドリルダウンに使用するページ・アイテムとしてP1_EMP_DEPTH 、P1_EMP_PARENT_UNIQUE_NAME を作成します。
対話モード・レポートのリージョン売上 の上でコンテキスト・メニュー を開き、ページ・アイテムの作成 を実行します。
作成されたページ・アイテムの
識別 の
名前 は
P1_CAL_DEPTH 、
タイプ として
選択リスト を選びます。
ラベル は
日付レベル とします。
LOV の
タイプ として
SQL問合せ を選択し、
SQL問合せ として以下を記述します。
追加値の表示 、
NULL値の表示 ともに
OFF にします。ビュー
USER_ANALYTIC_VIEW_LEVELS より、日付ディメンジョンの階層を取り出しています。
select level_name d, depth r
from
(
select level_name, ( order_num + 1 ) depth
from user_analytic_view_levels
where 1 =1
and analytic_view_name = 'AVT_EMP_SALES_AV'
and dimension_alias = 'AVT_DATE_DIM'
and hier_alias = 'AVT_CALENDAR_HIER'
union
select 'ALL' level_name, 0 depth from dual
)
order by depth asc
さらにページ・アイテムを作成します。識別 の名前 はP1_CAL_PARENT_UNIQUE_NAME 、タイプ には表示のみ を選択します。ラベル は親日付レベル とします。レイアウト の新規行の開始 はOFF にします。
日付ディメンジョンに続いて、マネージャー・ディメンジョンに関わるページ・アイテムを作成します。
新たにページ・アイテムを作成します。ページ・アイテムP1_CAL_DEPTHと同様の設定ですが、識別 の名前 をP1_EMP_DEPTH とし、ラベル はマネージャー・レベル とします。LOV のSQL問合せ を以下にします。
select level_name d, depth r
from
(
select level_name, ( order_num + 1 ) depth
from user_analytic_view_levels
where 1 =1
and analytic_view_name = 'AVT_EMP_SALES_AV'
and dimension_alias = 'AVT_EMP_DIM'
and hier_alias = 'AVT_EMPLOYEE_HIER'
union
select 'ALL' level_name, 0 depth from dual
)
order by depth asc
さらにページ・アイテムを作成し、P1_CAL_PARENT_UNIQUE_NAMEと同様の設定を行います。識別 の名前 はP1_EMP_PARENT_UNIQUE_NAME 、ラベル は親マネージャー・レベル とします。
レポートのドリルダウンに使用するページ・アイテムが作成されたので、対話モード・レポートのソース のSQL問合せ を以下に変更します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
select
case
when avt_calendar_hier.is_leaf = 0 then
'<a href="' ||
apex_page.get_url(
p_items => 'P1_CAL_DEPTH,P1_CAL_PARENT_UNIQUE_NAME',
p_values => (:P1_CAL_DEPTH+1) || ',' || avt_calendar_hier.member_unique_name
)
|| '">' || avt_calendar_hier.member_name || '</a>'
else
'<a href="' ||
apex_page.get_url(
p_page => 2,
p_clear_cache => 'RIR',
p_items => 'IR_DATE_WID',
p_values => avt_calendar_hier.member_name
)
|| '">' || avt_calendar_hier.member_name || '</a>'
end cal_member_name
, avt_calendar_hier.member_unique_name cal_member_unique_name
, avt_calendar_hier.parent_unique_name cal_parent_unique_name
, avt_calendar_hier.parent_level_name cal_parent_level_name
, avt_calendar_hier.depth cal_depth
,
case
when avt_employee_hier.is_leaf = 0 then
'<a href="' ||
apex_page.get_url(
p_items => 'P1_EMP_DEPTH,P1_EMP_PARENT_UNIQUE_NAME',
p_values => (:P1_EMP_DEPTH+1) || ',' || avt_employee_hier.member_unique_name
)
|| '">' || avt_employee_hier.member_name || '</a>'
else
'<a href="' ||
apex_page.get_url(
p_page => 2,
p_clear_cache => 'RIR',
p_items => 'IR_EMPNO',
p_values => avt_employee_hier.member_name
)
|| '">' || avt_employee_hier.member_name || '</a>'
end emp_member_name
, avt_employee_hier.member_unique_name emp_member_unique_name
, avt_employee_hier.parent_unique_name emp_parent_unique_name
, avt_employee_hier.parent_level_name emp_parent_level_name
, avt_employee_hier.depth emp_depth
/* メジャーのデフォルトは合計(SUM) */
, amount
/* その他のメジャー */
, round(avg_amount,0) avg_amount
, cnt_amount
, min_amount
, max_amount
from avt_emp_sales_av
hierarchies (avt_calendar_hier, avt_employee_hier)
where 1=1
/* 日付のドリルダウン */
and avt_calendar_hier.depth = :P1_CAL_DEPTH
and
(
:P1_CAL_PARENT_UNIQUE_NAME is null
or
:P1_CAL_PARENT_UNIQUE_NAME = avt_calendar_hier.parent_unique_name
)
/* マネージャのドリルダウン */
and avt_employee_hier.depth = :P1_EMP_DEPTH
and
(
:P1_EMP_PARENT_UNIQUE_NAME is null
or
:P1_EMP_PARENT_UNIQUE_NAME = avt_employee_hier.parent_unique_name
)
この後、動的アクションを使って対話モード・レポートのリフレッシュを実装するため、送信するページ・アイテム として、作成した4つのページ・アイテムP1_CAL_DEPTH 、P1_CAL_PARENT_UNIQUE_NAME 、P1_EMP_DEPTH 、P1_EMP_PARENT_UNIQUE_NAME のすべてを指定します。
ページ・アイテムP1_CAL_DEPTH が変更 されたときに、リージョン売上 をリフレッシュ します。
ページ・アイテムP1_CAL_DEPTH 上でコンテキスト・メニュー を開き、動的アクションの作成 を実行します。
作成された動的アクションの識別 の名前 は日付レベルの変更 とします。ページ・アイテム上で動的アクションを作成した場合は、タイミング はデフォルトで、イベント が変更 、選択タイプ がアイテム で、アイテム として動的アクションの作成を実行したP1_CAL_DEPTH になります。この設定はそのまま使います。
ページ・アイテムP1_CAL_DEPTHを変更したときは、親となるメンバーでの絞り込み(ドリルダウン)を解除して選択したレベルのすべての行が一覧されるようにします。そのため、ページ・アイテムの変更時にP1_CAL_PARENT_UNIQUE_NAMEをクリアします。
デフォルトで作成されたTRUEアクション である表示 を選択します。識別 のアクション としてクリア を選択し、影響を受ける要素 の選択タイプ にアイテム 、アイテム としてP1_CAL_PARENT_UNIQUE_NAME を指定します。
ページ・アイテムのクリア後にリージョン売上をリフレッシュします。
True のノード上でコンテキスト・メニュー を表示させ、TRUEアクションの作成 を実行します。
作成されたTRUEアクション の識別 のアクション としてリフレッシュ を選択します。影響を受ける要素 として、選択タイプ にリージョン 、リージョン に売上 を指定します。
ページ・アイテムP1_CAL_DEPTHに対する動的アクションの設定は以上です。
同様の動的アクションを、ページ・アイテムP1_EMP_DEPTHに対して作成します。
ページ・アイテムP1_EMP_DEPTH に動的アクションを作成します。識別 の名前 はマネージャー・レベルの変更 とします。
クリア するページ・アイテム はP1_EMP_PARENT_UNIQUE_NAME です。
TRUEアクションとして、リージョン売上 のリフレッシュ を作成します。
対話モード・レポートの列CAL_MEMBER_NAMEおよびEMP_MEMBER_NAMEは、ドリルダウンをするリンクを生成します。生成されたHTMLがそのまま表示されるよう、列CAL_MEMBER_NAME とEMP_MEMBER_NAME の両方を選択し、セキュリティ の特殊文字をエスケープ をOFF に変更します。
リンクをクリックしてレポートのドリルダウンを行う際に、ページ・アイテムP1_CAL_DEPTHやP1_EMP_DEPTHの値が破棄されます。このため画面上に警告が現れますが、この警告は無視できるため、ページ・プロパティの
ナビゲーション の
保存されていない変更の警告 を
OFF にします。
最後に売上詳細を表示するページを作成します。
ページの作成 を実行し、ページ作成ウィザード を起動します。
レポート を選択します。
対話モード・レポート を選択します。
ページ属性 を設定します。
ページ番号 は
2 とします。これはレポートのSQLに埋め込んであるため、他の番号にするとリンクが無効になります。そのため、必ず2を指定します。
ページ名 は
売上詳細 、
ページ・モード として
モーダル・ダイアログ を選択します。
次 へ進みます。
モーダル・ダイアログなので、ナビゲーションのプリファレンス はデフォルトのこのページとナビゲーション・メニュー・エントリを関連付けない のままにします。
次 へ進みます。
データ・ソース としてローカル・データベース 、ソース・タイプ としてSQL問合せ を選択します。SQL SELECT文を入力 に以下を記述します。
作成 をクリックします。
select
e. empno
, e. ename
, s. date_wid
, s. amount
from avt_emp_sales s join avt_employees e
on s. emp_wid = e. row_wid
売上詳細のページが作成されます。
以上で分析ビューを扱うサンプル・アプリケーションが作成できました。
動作確認
本記事の先頭にあるGIF動画の操作になります。
日付レベル、マネージャ・レベルともにALLを選択します。日付(Cal Member Name)、マネージャー(Emp Member Name)ともにTotalで、集計は表AVT_EMP_SALESの全行を対象にしています。
Cal Member Name のTotal をクリックします。
日付レベル がCAL_YEAR に変わります。ただし、表AVT_EMP_SALESには2022年の情報しかないため、集計結果は2022年で集計した一行だけになります。
Cal Member Name の2022 をクリックします。
日付レベル が
CAL_QTR に変わります。四半期毎に集計された結果が表示されます。
Cal Member Name の
3 をクリックします。
日付レベル がCAL_MONTH に変わります。親日付レベルは[CAL_QTR].&[3] となり、レポートされる月が第三四半期に限定されます。
Cal Member Name の08 をクリックします。
日付レベル が
CAL_DAY に変わります。
親日付レベル は
[CAL_MONTH].&[08] となり、レポートされる日付が8月に限定されます。
Cal Member Name の20220801 をクリックします。
日付ディメンジョンで日付が末端になります。そのため、分析ビューとしてのドリルダウンではなく、ファクト表を検索した結果を表示します。
レポートのソースのSELECT文で、レベルが末端(IS_LEAFが0ではない)の場合、分析ビューをドリルダウンする代わりに、詳細ページを開くようにCASE文を記述しています。
以上で分析ビューの動作が確認できました。
マネージャーの階層も同様の手順で確認できます。
日付レベル がCAL_MONTH、親日付レベル が[CAL_QTR].&[1] 、つまり第一四半期の月毎に、マネージャー・レベル がLVL2_MGR 、つまり社長直下となるすべてのマネージャーごとに売上を集計したレポートになります。
マネージャーの階層では、レベルの末端になると従業員名の代わりに従業員番号が表示されます。
分析ビューの動作を確認するための最低限のUIですが、分析ビューの使い方の参考にしていただけると幸いです。
分析ビューがあらかじめ作成されていれば、APEXアプリケーションでレポートやチャートを作成する際に、GROUP BYを使った集計関数などをSQLとして記述しなくて済みます。
分析ビューのその他の機能
本記事で紹介した内容は分析ビューの基本です。この他にも色々な機能を使ったサンプルがLiveSQL.oracle.comに載っています。
時刻の計算(Creating Time Series Calculations in Analytic View)
マテリアライズド・ビューによる集計のキャッシュ(Using the Analytic View Materialized Aggregate Cache)
複数言語の対応(Adding Multiple Language Support to Analytic Views)
SHARE_OFの使い方(Creating SHARE_OF (Hierarchical Ratio) Calculations in Analytic View)
FILTER FACTの使い方(Using FILTER FACT to Extend Analytic View Aggregation in SELECT)
今回のデータの準備では索引の作成は省いています。
パフォーマンス面で検討する価値がありそうなのは以下の定義でしょうか。
表AVT_CALENDARの主キー定義
alter table avt_calendar modify ( row_id primary key );
表AVT_EMPLOYEESの主キー定義
alter table avt_employees modify ( row_wid primary key );
表AVT_EMP_SALESの列DATE_WIDへのビットマップ結合索引
create bitmap index avt_emp_sales_date_bjix
on avt_emp_sales( avt_calendar. row_wid)
from avt_emp_sales, avt_calendar
where avt_emp_sales. date_wid = avt_calendar. row_wid
nologging compute statistics ;
表AVT_EMP_SALESの列EMP_WIDへのビットマップ結合索引
create bitmap index avt_emp_sales_emp_bjix
on avt_emp_sales( avt_employees. row_wid)
from avt_emp_sales, avt_employees
where avt_emp_sales. emp_wid = avt_employees. row_wid
nologging compute statistics ;
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。事前に準備が必要なので、分析ビューを作成するDDLは含んでいません。
https://github.com/ujnak/apexapps/blob/master/exports/analyticviewsample.sql
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完