database - 如何在 Oracle 中生成排列?

标签 database oracle oracle10g oracle11g permutation

在 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 重复任意次数。

感谢您的任何建议。

最佳答案

请在此处找到生成组合的解决方案。这是我们之前在房地产开发软件中遇到的问题的一个很好的变体。

创建和填充数据模型

首先设置:

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;
/

协助意见

首先,我创建了一些 View 。但当然你也可以内联它们或使用 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 在优化方面做得不太理想。

当您的网站性能 Not Acceptable 时,请列出一些关键统计数据或添加再现场景。

关于database - 如何在 Oracle 中生成排列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12300774/

相关文章:

c# - C# bond 中有哪些可用的数据类型?

performance - 通过 JDBC 调用 PL/SQL 包性能问题

sql - 没有 XML 路径的逗号分隔列

java - 如果我总是在带有 varchar 的准备语句中设置 null 会发生什么?

sql - select 中的 if 语句 (ORACLE)

ruby-on-rails - Rails select - 不需要的自动类型转换

sql - 查询 : Show the name of the salesmen with more that 4 invoices in the same month

c# - 多站点 CMS - 每个站点的数据库,还是所有站点的一个数据库?

java - 通过java访问oracle sql字段

SQL 加入两次相同的表?