ここで組み合わせを生成するための解決策を見つけてください。これは、不動産開発用のソフトウェアで発生した以前の問題の優れた変形でした。
データモデルの作成と入力
最初のセットアップ:
create table contents
( item_purpose_code number
, item_category_id number
, item_id number
)
/
begin
insert into contents values (1, 101, 50);
insert into contents values (2, 202, 94);
insert into contents values (2, 202, 95);
commit;
end;
/
ビューの補助
まず、いくつかのビューを作成します。もちろん、それらをインライン化するか、 を使用することもできますwith
。
--
-- Add to each row the consecutive number of the driver columns
-- (here only item_purpose_code) and for each different value
-- for the driver columns a consecutive number that restarts
-- when a new driver column value starts.
--
create or replace force view sequencedrows
as
select item_purpose_code
, item_category_id
, item_id
, dense_rank()
over
( order
by item_purpose_code
) driver_seq
, row_number()
over
( partition
by item_purpose_code
order
by item_category_id
, item_id
)
values_per_driver_seq
from contents
/
--
-- Generate list of combinations.
--
create or replace force view combinations
as
select sys_connect_by_path (driver_seq || '-' || values_per_driver_seq, '#') || '#' combination
from sequencedrows
where level = ( select max(driver_seq) from sequencedrows )
start
with driver_seq = 1
connect
by
nocycle driver_seq = prior driver_seq + 1
/
combination
これらを使用すると、組み合わせがすでにフィールドに含まれており、行に番号が付けられているため、非常に簡単になります。
select c.combination
, s.item_purpose_code
, s.item_category_id
, s.item_id
from combinations c
join sequencedrows s
on c.combination like '%#' || to_char(s.driver_seq) || '-' || to_char(s.values_per_driver_seq) || '#%'
order
by c.combination
, s.driver_seq
, s.values_per_driver_seq
/
結果は次のとおりです。
#1-1#2-1# 1 101 50
#1-1#2-1# 2 202 94
#1-1#2-2# 1 101 50
#1-1#2-2# 2 202 95
パフォーマンス
データ量とインデックスによっては、インタラクティブに使用するにはパフォーマンスが不十分な場合があります。しかし、私たちの不動産開発パッケージでは、Oracle 11g 以降、生成された 50K 行のパフォーマンスでも許容できることがわかりました。Oracle 10g は、最適化に関してあまり最適ではありませんでした。
サイトのパフォーマンスが許容できない場合は、いくつかの重要な統計をリストするか、再現シナリオを追加してください。