Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In SQL, How can I generate every possible unique combination of 5!56?

I have a TABLE "elements" with one COLUMN "number", type SMALLINT that contains numbers 1 thru 56. How can I generate unique sets of 5 numbers of every possible combination from 1 to 56, using an SQL statement?

In APL (programming language) a simple dyadic function 5!56 does the trick!

EDIT: In good ole MS-DOS QBASIC, I accomplished it like this:

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 

This, by the way, created my load file into an INFORMIX-SQL table

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

I used combos.sum to generate a bell curve graph, showing the count of combinations having the same sum of each element.

like image 601
Frank R. Avatar asked Dec 05 '22 17:12

Frank R.


2 Answers

If by "unique sets" you mean what I think you do (sorry, I don't know APL!), you can write:

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
;

"could this be accomplished without actually having to store the elements in a table?.. i.e. let the server do it without resorting to table I/O? "

Yes, there is an Oracle trick to generate data on the fly, using the hierarchical query and the CTE syntax:

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
;
like image 154
ruakh Avatar answered Dec 08 '22 06:12

ruakh


If you want to include pairs of identical numbers, e.g. (5,5):

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

If you want to only have different numbers in each pair:

SELECT e1.number AS number1
      ,e2.number AS number2
FROM   elements e1
      ,elements e2
WHERE  e1.number < e2.number;
like image 22
Jeffrey Kemp Avatar answered Dec 08 '22 05:12

Jeffrey Kemp