DBMS_FREQUENT_ITEMSETパッケージは頻度の高い項目セットのカウントを可能にします。2つのファンクションは入力カーソル形式の違いを除けば同じものです。
この章では、次の項目について説明します。
表58-1 DBMS_FREQUENT_ITEMSETパッケージのサブプログラム
| サブプログラム | 説明 |
|---|---|
|
|
' |
|
|
' |
この表ファンクションの目的は、'HORIZONTAL'行形式の入力データのカーソル、サポートしきい値、最小項目セット長、最大項目セット長、含める項目、除外する項目を指定して、すべての頻度の高い項目セットをカウントすることです。結果は、項目セット、サポート、長さ、カウントされたトランザクション合計数の形式の行からなる表になります。
'HORIZONTAL'行形式では、各行に単一のトランザクションのすべての項目IDが含まれます。すべての項目が一緒に出力されるため、トランザクションIDは必要ありません。
この表ファンクションの利点は、アプリケーションのデータがすでに水平形式で保持されている場合に、データベースがトランザクション形式の行を水平形式に変換する手順をスキップできることです。
構文
DBMS_FREQUENT_ITEMSET.FI_HORIZONTAL(
tranx_cursor IN SYSREFCURSOR,
support_threshold IN NUMBER,
itemset_length_min IN NUMBER,
itemset_length_max IN NUMBER,
including_items IN SYS_REFCURSOR DEFAULT NULL,
excluding_items IN SYS_REFCURSOR DEFAULT NULL)
RETURN TABLE OF ROW (
itemset [Nested Table of Item Type DERIVED FROM tranx_cursor],
support NUMBER,
length NUMBER,
total_tranx NUMBER);
パラメータ
表58-2 FI_HORIZONTALファンクションのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
ファンクションのコール時にユーザーが指定するカーソル・パラメータ。戻される列数に制限はありません。カーソルの各列が項目を表します。カーソルのすべての列が同じデータ型である必要があります。項目IDは数値型または文字型です( |
|
|
トランザクション合計カウントの分数。項目セットは、[発生したトランザクション数]÷[トランザクション合計数]がこの分数を超える場合に「頻度の高い」と呼ばれます。パラメータは |
|
|
対象となる頻度の高い項目セットの最小長。パラメータは1から20までの |
|
|
対象となる頻度の高い項目セットの最大長。このパラメータは1から20までの |
|
|
項目のリストをフェッチするカーソル。戻される頻度の高い項目セットには、リストの項目が少なくとも1つ存在する必要があります。デフォルトは |
|
|
項目のリストをフェッチするカーソル。戻される頻度の高い項目セットにはリストの項目が含まれません。デフォルトは |
戻り値
表58-3 FI_HORIZONTALファンクションの戻り値
| パラメータ | 説明 |
|---|---|
support |
頻度の高い項目セットが発生するトランザクション数。これは |
itemset |
頻度の高い項目セットとして計算される項目のコレクション。これは、入力カーソルの項目列タイプである項目タイプのネストした表として戻されます。 |
length |
頻度の高い項目セットの項目数。これは |
total_tranx |
トランザクション合計数。これは |
例
表horiz_table_inがあるとします。
horiz_table_in(iid1 VARCHAR2(30), iid2 VARCHAR2(30), iid3 VARCHAR2(30), iid4 VARCHAR2(30), iid5 VARCHAR2(30));
また、horiz_table_inのデータは次のようなものであるとします。
('apple', 'banana', NULL, NULL, NULL)
('apple', 'milk', 'banana', NULL, NULL)
('orange', NULL, NULL, NULL, NULL)
30%のサポートしきい値が指定された頻度の項目の組合せを見つけ、ただし、項目セットに('apple','banana','orange')のうちの少なくとも1つを含むが、('milk')を除外する必要があるとします。次の問合せを使用します。
CREATE TYPE fi_varchar_nt AS TABLE OF VARCHAR2(30);
SELECT CAST(itemset as FI_VARCHAR_NT)itemset, support, length, total_tranx
FROM table(DBMS_FREQUENT_ITEMSET.FI_HORIZONTAL(
CURSOR(SELECT iid1, iid2, iid3, iid4, iid5
FROM horiz_table_in),
0.3,
2,
5,
CURSOR(SELECT * FROM table(FI_VARCHAR_NT
('apple','banana','orange'))),
CURSOR(SELECT * FROM table(FI_VARCHAR_NT('milk')))));
このファンクションは、'TRANSACTIONAL'行形式の入力データのカーソル、サポートしきい値、最小項目セット長、最大項目セット長、含める項目、除外する項目を指定して、すべての頻度の高い項目セットをカウントします。結果は項目セット、サポート、長さ、トランザクション合計数の形式の行からなる表になります。
'TRANSACTIONAL'行形式では、各トランザクションが複数行にわたります。指定したトランザクションのすべての行のトランザクションIDは同じであり、各行の項目IDは異なります。指定したトランザクションIDを共有するすべての項目IDを組み合せると、単一のトランザクションになります。
構文
DBMS_FREQUENT_ITEMSET.FI_TRANSACTIONAL (
tranx_cursor IN SYSREFCURSOR,
support_threshold IN NUMBER,
itemset_length_min IN NUMBER,
itemset_length_max IN NUMBER,
including_items IN SYS_REFCURSOR DEFAULT NULL,
excluding_items IN SYS_REFCURSOR DEFAULT NULL)
RETURN TABLE OF ROW (
itemset [Nested Table of Item Type DERIVED FROM tranx_cursor],
support NUMBER,
length NUMBER,
total_tranx NUMBER);
パラメータ
表58-4 FI_TRANSACTIONALファンクションのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
ファンクションのコール時にユーザーが指定するカーソル・パラメータ。戻される行に2つの列があります。先頭の列はトランザクションIDで、2番目の列は項目IDです。項目IDは数値型または文字型です( |
|
|
トランザクション合計カウントの分数。項目セットは、[発生したトランザクション数]÷[トランザクション合計数]がこの分数を超える場合に「頻度の高い」と呼ばれます。パラメータは |
|
|
対象となる頻度の高い項目セットの最小長。パラメータは1から20までの |
|
|
対象となる頻度の高い項目セットの最大長。このパラメータは1から20までの |
|
|
項目のリストをフェッチするカーソル。戻される頻度の高い項目セットには、リストの項目が少なくとも1つ存在する必要があります。デフォルトは |
|
|
項目のリストをフェッチするカーソル。戻される頻度の高い項目セットにはリストの項目が含まれません。デフォルトは |
戻り値
表58-5 FI_TRANSACTIONALファンクションの戻り値
| パラメータ | 説明 |
|---|---|
support |
頻度の高い項目セットが発生するトランザクション数。これは |
itemset |
頻度の高い項目セットとして計算される項目のコレクション。これは、入力カーソルの項目列タイプである項目タイプのネストした表として戻されます。 |
length |
頻度の高い項目セットの項目数。これは |
total_tranx |
トランザクション合計数。これは |
使用上の注意
アプリケーションは、入力項目タイプのネストした表タイプを事前定義し、表へのロードなど、処理を続ける前に、出力項目セットをこの事前定義されたネストした表タイプに変換する必要があります。
例
入力の表tranx_table_inが次のようなものであるとします。
(1, 'apple') (1, 'banana') (2, 'apple') (2, 'milk') (2, 'banana') (3, 'orange')
ユーザーは60%のサポートしきい値を満たし、項目セット長が2以上の項目セット(つまり、(apple, banana))を検索しようとしています。
このファンクションの出力には、次の出力行が含まれます。
itemset=('apple','banana'), support=2, length=2, total_tranx=3
項目タイプがネストした表を作成してから、頻度の高い項目セットのカウントを実行する問合せを送信する必要があります。この例では、項目がVARCHAR2(30)であるため、VARCHAR2(30)のネストした表を作成する必要があります。
CREATE TYPE fi_varchar_nt AS TABLE OF VARCHAR2(30);
SELECT CAST(itemset as FI_VARCHAR_NT) itemset, support, length, total_tranx
FROM table(DBMS_FREQUENT_ITEMSET.FI_TRANSACTIONAL(
cursor(SELECT tid, iid FROM tranx_table_in),
0.6,
2,
5,
NULL,
NULL));
カウントに特定の項目を含め、特定の項目を除外する方法についての別の例を以下に示します。
SELECT CAST(itemset as FI_VARCHAR_NT)itemset, support, length, total_tranx
FROM table(DBMS_FREQUENT_ITEMSET.FI_TRANSACTIONAL(
CURSOR(SELECT tid, iid FROM tranx_table_in),
0.6,
2,
5,
CURSOR(SELECT * FROM table(FI_VARCHAR_NT
('apple','banana','orange'))),
CURSOR(SELECT * FROM table(FI_VARCHAR_NT('milk')))));
項目を含めるかまたは除外するパラメータを使用して、アプリケーションで要求されない項目セットを無視することで実行をさらに最適化できます。
また、コレクション・ネスト解除によって、トランザクション出力を使用することもできます。
SELECT
bt.setid, nt.*
FROM
(SELECT cast(Itemset as FI_VARCHAR_NT) itemset, rownum setid
FROM table(
DBMS_FREQUENT_ITEMSET.FI_TRANSACTIONAL(
CURSOR(SELECT tid, iid FROM tranx_table_in), 0.6, 2, 5,
NULL, NULL))) bt,
table(bt.itemset) nt;
insert文を使用して、頻度の高い項目セットをネストした表にロードする場合は、パフォーマンスの観点から、NESTED_TABLE_FAST_INSERTヒントを使用することをお薦めします。
CREATE TABLE fq_nt (coll FI_VARCHAR_NT) NESTED TABLE coll STORE AS
coll_nest;
INSERT /*+ NESTED_TABLE_FAST_INSERT */ INTO fq_nt
SELECT cast(itemset as FI_VARCHAR_NT)
FROM table(DBMS_FREQUENT_ITEMSET.FI_TRANSACTIONAL(
cursor(SELECT tid, iid FROM tranx_table_in), 0.6, 2, 5,
NULL, NULL));
PL/SQLカーソル内でパッケージを使用する場合は、表ファンクションの戻り値の型を変換する必要があるので注意してください。
CREATE TYPE fi_res AS OBJECT (
itemset FI_VARCHAR_NT,
support NUMBER,
length NUMBER,
total_tranx NUMBER
);
/
CREATE TYPE fi_coll AS TABLE OF fi_res;
/
DECLARE
cursor freqC is
SELECT Itemset
FROM table(
CAST(DBMS_FREQUENT_ITEMSET.FI_TRANSACTIONAL(
cursor(SELECT tid, iid FROM tranx_table_in), 0.6, 2, 5,
NULL, NULL) AS fi_coll));
coll_nt FI_VARCHAR_NT;
num_rows int;
num_itms int;
BEGIN
num_rows := 0;
num_itms := 0;
OPEN freqC;
LOOP
FETCH freqC INTO coll_nt;
EXIT WHEN freqC%NOTFOUND;
num_rows := num_rows + 1;
num_itms := num_itms + coll_nt.count;
END LOOP;
CLOSE freqC;
DBMS_OUTPUT.PUT_LINE('Totally ' || num_rows || ' rows ' || num_itms || '
items were produced.');
END;
/