Oracle SQL中组合语言的使用

时间:2018-08-30 13:20:00

标签: sql oracle

可能会使用一些帮助或见解,导致我发疯。.

  • 情况:我有一张球员ID表,值分别为1,2,3 ..至7。
  • 目标:要从可用球员中建立4名球员的名单(在我们的示例中有7名)。它是经典的组合任务,我们需要计算C(k,n)。在我们的情况下,C(4,7)= 840/24 = 35。因此,有35种方法可以建立名册。我想创建一个具有玩家ID的名册表。这是当前的脚本,用于构建当前的名册表:

with comb_tbl as( select tmp_out.row_num, regexp_substr(tmp_out.comb_sets,'[^,]+',1,1) plr_id_1, regexp_substr(tmp_out.comb_sets,'[^,]+',1,2) plr_id_2, regexp_substr(tmp_out.comb_sets,'[^,]+',1,3) plr_id_3, regexp_substr(tmp_out.comb_sets,'[^,]+',1,4) plr_id_4 from( select rownum row_num, substr(tmp.combinations,2) comb_sets from( select sys_connect_by_path(plr.plr_id, ',') combinations from( select 1 plr_id from dual union select 2 plr_id from dual union select 3 plr_id from dual union select 4 plr_id from dual union select 5 plr_id from dual union select 6 plr_id from dual union select 7 plr_id from dual) plr connect by nocycle prior plr.plr_id != plr.plr_id) tmp where length(substr(tmp.combinations,2)) = 7) tmp_out) select tmp1.* from comb_tbl tmp1

  • 问题:它创建了840种可能性,但是我需要删除“相同”的可能性,例如名册(1,2,3,4)与名册(2,1是“相同”的) ,3,4)。欢迎有任何见解/评论/批评。也许方法本身是错误的?

3 个答案:

答案 0 :(得分:3)

可能的花名册与七元素集的四个元素的ORDERED子集之间存在1-1对应关系。

在您的CONNECT BY子句中,您仅检查玩家ID是否不同,而不是按升序排列。将!=中的<更改为CONNECT BY,它将起作用。 (此外,您将不再需要NOCYCLE。)

答案 1 :(得分:2)

这可以是一种加入方式:

with plr(plr_id) as 
    ( select level from dual connect by level <= 7)
select p1.plr_id, p2.plr_id, p3.plr_id, p4.plr_id
from plr p1
      inner join plr p2
        on(p1.plr_id < p2.plr_id)  
      inner join plr p3
        on(p2.plr_id < p3.plr_id)
      inner join plr p4
        on(p3.plr_id < p4.plr_id) 

例如,使用n=5,您将拥有:

    PLR_ID     PLR_ID     PLR_ID     PLR_ID
---------- ---------- ---------- ----------
         1          2          3          4
         1          2          3          5
         1          2          4          5
         1          3          4          5
         2          3          4          5

答案 2 :(得分:1)

这不是答案;这只是我先前评论的延续:

通过进行这些其他更改,您的查询最终可能会类似于:

SELECT regexp_substr(tmp_out.comb_sets,'[^,]+',1,1) plr_id_1,
       regexp_substr(tmp_out.comb_sets,'[^,]+',1,2) plr_id_2,
       regexp_substr(tmp_out.comb_sets,'[^,]+',1,3) plr_id_3,
       regexp_substr(tmp_out.comb_sets,'[^,]+',1,4) plr_id_4
FROM   (SELECT sys_connect_by_path(plr.plr_id, ',') comb_sets,
               LEVEL lvl
        FROM   (select 1 plr_id from dual union all
                select 2 plr_id from dual union all
                select 3 plr_id from dual union all
                select 4 plr_id from dual union all
                select 5 plr_id from dual union all
                select 6 plr_id from dual union all
                select 7 plr_id from dual) plr
        CONNECT BY PRIOR plr.plr_id < plr.plr_id
                   AND LEVEL <= 4) tmp_out
WHERE lvl = 4;

IMO,比原始查询更易于阅读和理解。