在SQL中,如何生成5!56的每个可能的唯一组合?

时间:2012-03-30 01:51:07

标签: sql oracle informix factorial apl

我有一个带有一个COLUMN“number”的TABLE“elements”,类型为SMALLINT,包含数字1到56.如何使用SQL语句生成从1到56的每个可能组合的5个数字的唯一集合?< / p>

在APL(编程语言)中,一个简单的二元函数5!56可以解决这个问题!

编辑:在好的MS-DOS QBASIC中,我完成了这样的事情:

10  OPEN "C:\5NUMBERS.OUT" FOR OUTPUT ACCESS READ WRITE AS #1
12  LET SER = 0

15  LET E = 56
30      FOR B5 = 5 TO E
40          FOR B4 = 4 TO E
50              FOR B3 = 3 TO E
60                  FOR B2 = 2 TO E
70                      FOR B1 = 1 TO E
80

88  IF B5 = B1 THEN 190
89  IF B5 = B2 THEN 190
90  IF B5 = B3 THEN 190
91  IF B5 = B4 THEN 190

92  IF B4 = B1 THEN 180
93  IF B4 = B2 THEN 180
94  IF B4 = B3 THEN 180

95  IF B3 = B1 THEN 170
96  IF B3 = B2 THEN 170

97  IF B2 = B1 THEN 160

98 LET SER = SER + 1

100 PRINT #1, SER; "|";
130 PRINT #1, B1; "|";
131 PRINT #1, B2; "|";
132 PRINT #1, B3; "|";
133 PRINT #1, B4; "|";
134 PRINT #1, B5; "|";
140 PRINT #1, B1 + B2 + B3 + B4 + B5; "|"

150                     NEXT B1
160                 NEXT B2
170             NEXT B3
180         NEXT B4
190     NEXT B5
205 CLOSE
210 END
220 SYSTEM 

顺便说一下,这将我的加载文件创建到INFORMIX-SQL表

TABLE combos
(
seq_id SERIAL,
ball_1 SMALLINT,
ball_2 SMALLINT,
ball_3 SMALLINT,
ball_4 SMALLINT,
ball_5 SMALLINT,
sum    SMALLINT
);

我使用combos.sum生成钟形曲线图,显示每个元素总和相同的组合计数。

4 个答案:

答案 0 :(得分:6)

如果用“独特的套装”表示你的意思(抱歉,我不知道APL!),你可以写:

SELECT e1.number,   e2.number,   e3.number,   e4.number,   e.number
  FROM elements e1, elements e2, elements e3, elements e4, elements e5
 WHERE e1.number < e2.number
   AND e2.number < e3.number
   AND e3.number < e4.number
   AND e4.number < e5.number
;

  

“这可以在没有实际存储的情况下完成   表中的元素?...即让服务器执行它而不诉诸   表I / O? “

是的,有一个Oracle技巧可以使用分层查询和CTE语法动态生成数据:

WITH elements AS
( select rownum as number
  from dual
  connect by level <= 56 )
SELECT e1.number,   e2.number,   e3.number,   e4.number,   e.number
  FROM elements e1, elements e2, elements e3, elements e4, elements e5
 WHERE e1.number < e2.number
   AND e2.number < e3.number
   AND e3.number < e4.number
   AND e4.number < e5.number
;

答案 1 :(得分:5)

如果您想要包含一对相同的数字,例如(5,5):

SELECT e1.number AS number1
      ,e2.number AS number2
FROM   elements e1
      ,elements e2
WHERE  e1.number <= e2.number;

如果您希望每对中只有不同的数字:

SELECT e1.number AS number1
      ,e2.number AS number2
FROM   elements e1
      ,elements e2
WHERE  e1.number < e2.number;

答案 2 :(得分:3)

并非我实际上使用数据库进行此类任务,但是,如果你被迫在酷刑或肢解的威胁下这样做,我会调查类似的事情({{1} }出于格式化目的,缩短为number

num

它基本上交叉将表连接到自身以生成五列,然后过滤掉任何数字相同的列。

请注意,这会为您提供排列:select a.num, b.num, c.num, d.num, e.num from elements a, elements b, elements c, elements d, elements e where a.num <> b.num and a.num <> c.num and a.num <> d.num and a.num <> e.num and b.num <> c.num and b.num <> d.num and b.num <> e.num and c.num <> d.num and c.num <> e.num and d.num <> e.num (1,2,3,4,5)不同。如果你想要组合(顺序无关紧要),你会使用稍微不同的条款:

(1,2,3,5,4)

答案 3 :(得分:2)

我的第一个想法是做一个笛卡尔,只是确保每个记录都高于最后一个,所以你不会在任何地方重复数字。现在这将创建类似

的东西
1,2,3,4,5
1,2,3,4,6
1,2,3,4,7, etc...
but will NEVER have the reverse or mixed such as
6,4,3,2,1
6,2,4,3,1
4,6,1,2,3 
as those would already be a "same" set of numbers (more along the lines of lottery style where no same number appears twice)

但是,如果您还想要重复,例如

1,1,1,1,1
1,2,1,2,1
1,2,3,1,1 

如果数字可以重复数字,只需将相等更改为&lt; =而不仅仅是&lt;。

select
      YT1.Number as Num1,
      YT2.Number as Num2,
      YT3.Number as Num3,
      YT4.Number as Num4,
      YT5.Number as Num5
   from
      YourTable YT1
         JOIN YourTable YT2
            ON YT1.Number < YT2.Number
            JOIN YourTable YT3
               ON YT2.Number < YT3.Number
               JOIN YourTable YT4
                  ON YT3.Number < YT4.Number
                  JOIN YourTable YT5
                     ON YT4.Number < YT5.Number