2015-12-03 113 views
0

我不确定这是什么正确的搜索词,请让我知道如果已经有这个答案。 如: 我有这些数据Oracle pl/sql排列和组合

A 
B 
C 
D 
E 

什么是计算每增加一个可能的组合的最佳方式?如:

A 
A+B 
A+C 
A+D 
A+E 
A+B+C 
A+B+D 
A+B+E 
A+C+D 
A+C+E 
A+C+D+E 
A+B+C+D 
A+B+C+E 
A+B+C+D+E 
B 
B+C 
B+D 
B+E 
B+C+D 
B+C+E 
B+C+D+E 
C 
C+D 
C+E 
... 
The list goes on....... 

有什么办法可以做到这一点?

5个数据不固定。我可能有10 .. 20或50或1000 :(

谢谢

+0

你只是试图做的可能的组合计数?这是一个众所周知的公式,不需要任何SQL。或者你是否试图实际列举每种可能的组合? – Rabbit

+0

你好,不,我不是只想做一些可能的组合。我需要每个组合的结果 –

+0

为什么你需要这样的东西?您的服务器将无法处理它。该表几乎不可用 – Rabbit

回答

2

在SQL中,你几乎可以用这一套left join就做这个。

select (t1.col + coalesce(t2.col, 0) + coalesce(t3.col, 0) + 
     coalesce(t4.col, 0) + coalesce(t5.col, 0) 
     ) as sumcombo 
from t t1 left join 
    t t2 
    on t1.col < t2.col left join 
    t t3 
    on t2.col < t3.col left join 
    t t4 
    on t3.col < t4.col left join 
    t t5 
    on t4.col < t5.col; 

它不相当的工作,因为你永远无法得到的只是“A”的实例,而不是:。

with t as (
     select col 
     from table 
     union all 
     select NULL 
     from dual 
    ) 
select (t1.col + coalesce(t2.col, 0) + coalesce(t3.col, 0) + 
     coalesce(t4.col, 0) + coalesce(t5.col, 0) 
     ) as sumcombo 
from table t1 left join 
    t t2 
    on t1.col < t2.col or t2.col is null left join 
    t t3 
    on t2.col < t3.col or t3.col is null left join 
    t t4 
    on t3.col < t4.col or t4.col is null left join 
    t t5 
    on t4.col < t5.col or t5.col is null; 
+0

对不起,我没有在我的问题中明确说明。数据的数量是不固定的:(我可能有10或20或50或1000行 –

+2

列出1000个元素的所有排列在我的有生之年不会发生 –

+0

是的,我知道甚至50个元素将返回3 * 10^64的结果,这是荒谬的。是否有灵活的方式来做存储过程? –

1

这可以通过一个分层查询,首先需要解决,建立一个大的儿童柱col2用于连接离子:

-- your test data set 
with testdata as 
(select 'A' as col from dual 
    union 
    select 'B' from dual 
    union 
    select 'C' from dual 
    union 
    select 'D' from dual 
    union 
    select 'E' from dual), 

-- create child column 
testdata2 as 
(select t.col as col1, t.col as col2 from testdata t) 

select level, sys_connect_by_path(col1, '/') path 
    from testdata2 t 
connect by prior col1 < col2 
order by level, sys_connect_by_path(col1, '/'); 

结果:

1 /A 
1 /B 
1 /C 
1 /D 
1 /E 
2 /A/B 
2 /A/C 
2 /A/D 
2 /A/E 
2 /B/C 
2 /B/D 
2 /B/E 
2 /C/D 
2 /C/E 
2 /D/E 
3 /A/B/C 
3 /A/B/D 
3 /A/B/E 
3 /A/C/D 
3 /A/C/E 
3 /A/D/E 
3 /B/C/D 
3 /B/C/E 
3 /B/D/E 
3 /C/D/E 
4 /A/B/C/D 
4 /A/B/C/E 
4 /A/B/D/E 
4 /A/C/D/E 
4 /B/C/D/E 
5 /A/B/C/D/E