2012-09-06 64 views
2

在Oracle中,我有一個對象類型的表。如何在Oracle中生成排列?

我想生成的ITEM_PURPOSE_CODE所有排列。

表看起來是這樣的:

ITEM_PURPOSE_CODE ITEM_CATEGORY_ID ITEM_ID 
========================================== 
1     101    50 
2     202    94 
2     202    95 

我想什麼那麼,是產生一束代表置換表類型,例如:

ITEM_PURPOSE_CODE ITEM_CATEGORY_ID ITEM_ID 
========================================== 
1     101    50 
2     202    94 

ITEM_PURPOSE_CODE ITEM_CATEGORY_ID ITEM_ID 
========================================== 
1     101    50 
2     202    95 

顯然,這是一個非常簡單的例子。可以有任意數量的項目目的代碼(1到n),並且這些代碼可以針對不同的項目類別ID /項目ID重複任意次數。

感謝您的任何建議。

+1

我看就叫組合。在排列順序中很重要。 –

+2

聽起來像家庭作業,但你(或你的教授)是否可以想象笛卡爾產品? – tbone

+0

@Eric。 。 。你能描述你爲什麼要這麼做嗎?排列的數量增長得非常快,通常你不想將它們全部存儲在數據庫中。 –

回答

2

請找到解決這裏產生的組合。這是我們用於房地產開發的軟件中的一個很好的變體。

創建和填寫數據模型

首先設置:

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

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 

性能

-- 
-- 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和行進行了編號就變得很簡單

根據數據量和索引,性能上可能不足以用於交互式使用。然而,在我們的房地產開發軟件包中,我們發現即使擁有5萬行數據庫,Oracle 11g以後的表現也是可以接受的。 Oracle 10g在優化方面做得不夠理想。

當性能在您的站點不能接受的,請列出一些關鍵統計數據或添加再現場景。

+0

hi @Eric這個答案有助於解決您的問題?如果沒有,請添加什麼不成功的問題。當答案對您有幫助時,您是否可以通過點擊旁邊的空心綠色複選標記來接受它? –