ユーザー定義の集計関数を使用して複数のコレクションの共通部分を取得するソリューション:
Oracleセットアップ :
まず、ワークフローを保持するコレクションを定義します。
CREATE OR REPLACE TYPE VARCHAR2s_Table IS TABLE OF VARCHAR2(4000);
/
次に、集計プロセスで使用するオブジェクトを定義します。
CREATE OR REPLACE TYPE Varchar2sTableIntersection AS OBJECT(
intersection VARCHAR2s_Table,
STATIC FUNCTION ODCIAggregateInitialize(
ctx IN OUT Varchar2sTableIntersection
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateIterate(
self IN OUT Varchar2sTableIntersection,
value IN VARCHAR2s_Table
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateTerminate(
self IN OUT Varchar2sTableIntersection,
returnValue OUT VARCHAR2s_Table,
flags IN NUMBER
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateMerge(
self IN OUT Varchar2sTableIntersection,
ctx IN OUT Varchar2sTableIntersection
) RETURN NUMBER
);
/
CREATE OR REPLACE TYPE BODY Varchar2sTableIntersection
IS
STATIC FUNCTION ODCIAggregateInitialize(
ctx IN OUT Varchar2sTableIntersection
) RETURN NUMBER
IS
BEGIN
ctx := Varchar2sTableIntersection( NULL );
RETURN ODCIConst.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateIterate(
self IN OUT Varchar2sTableIntersection,
value IN VARCHAR2s_Table
) RETURN NUMBER
IS
BEGIN
IF value IS NULL THEN
NULL;
ELSIF self.intersection IS NULL THEN
self.intersection := value;
ELSE
self.intersection := self.intersection MULTISET INTERSECT value;
END IF;
RETURN ODCIConst.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateTerminate(
self IN OUT Varchar2sTableIntersection,
returnValue OUT VARCHAR2s_Table,
flags IN NUMBER
) RETURN NUMBER
IS
BEGIN
returnValue := self.intersection;
RETURN ODCIConst.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateMerge(
self IN OUT Varchar2sTableIntersection,
ctx IN OUT Varchar2sTableIntersection
) RETURN NUMBER
IS
BEGIN
IF self.intersection IS NULL THEN
self.intersection := ctx.intersection;
ELSIF ctx.intersection IS NULL THEN
NULL;
ELSE
self.intersection := self.intersection MULTISET INTERSECT ctx.intersection;
END IF;
RETURN ODCIConst.SUCCESS;
END;
END;
/
第三に、ユーザー定義の集計関数を作成します。
CREATE FUNCTION MULTISET_INTERSECT( collection VARCHAR2s_Table )
RETURN VARCHAR2s_Table
PARALLEL_ENABLE AGGREGATE USING Varchar2sTableIntersection;
/
クエリ1-コレクションとして出力 :
SELECT MULTISET_INTERSECT( workflows ) AS common_workflows
FROM (
SELECT role_id,
CAST(
COLLECT(
workflow_id
) AS VARCHAR2s_Table
) AS workflows
FROM workflow_detail
GROUP BY role_id
);
出力 :
COMMON_WORKFLOWS
----------------------
VARCHAR2S_TABLE( 'B' )
クエリ2-行として出力 :
SELECT t.COLUMN_VALUE AS common_workflows
FROM (
SELECT MULTISET_INTERSECT( workflows ) AS common
FROM (
SELECT role_id,
CAST(
COLLECT(
workflow_id
) AS VARCHAR2s_Table
) AS workflows
FROM workflow_detail
GROUP BY role_id
)
) cw
CROSS JOIN TABLE( cw.common ) t;
出力 :
COMMON_WORKFLOWS
----------------
B