【问题标题】:Oracle pl/sql permutation and combinationOracle pl/sql 排列组合
【发布时间】:2015-12-03 03:03:54
【问题描述】:

我不确定什么是正确的搜索词,如果已经有答案,请告诉我。 例如: 我有这些数据

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 :(

谢谢。

【问题讨论】:

  • 您只是想计算可能的组合吗?这是一个众所周知的公式,不需要任何 SQL。或者您是否在尝试枚举所有可能的组合?
  • 您好,不,我不是要计算可能的组合。我需要每个组合的结果
  • 你为什么需要这样的东西?您的服务器将无法处理它。该表几乎无法使用
  • 你试过正则表达式吗?
  • @vishnusable 我不确定正则表达式与这个问题有什么关系......

标签: sql oracle stored-procedures plsql


【解决方案1】:

在SQL中,你几乎可以用这组left joins做到这一点:

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;

【讨论】:

  • 对不起,我的问题没有明确说明。数据的数量不固定:(。我可能有 10 或 20 或 50 或 1000 行
  • 列出 1000 个元素的所有排列,这在我有生之年是不会发生的。
  • 是的,我知道。即使是 50 个元素也会返回 3*10^64 的结果,这很荒谬。从存储过程中是否有灵活的方法?
【解决方案2】:

这可以通过分层查询来解决。首先,再建一个子列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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    • 2017-12-18
    • 1970-01-01
    • 2013-11-20
    • 1970-01-01
    相关资源
    最近更新 更多