В SQL, как я могу создать каждую возможную уникальную комбинацию 5! 56? - PullRequest
4 голосов
/ 30 марта 2012

У меня есть ТАБЛИЦА «элементов» с одним КОЛОННЫМ «числом», тип SMALLINT, который содержит числа от 1 до 56. Как я могу генерировать уникальные наборы из 5 чисел каждой возможной комбинации от 1 до 56, используя инструкцию SQL?

В APL (язык программирования) простая диадическая функция 5! 56 делает свое дело!

РЕДАКТИРОВАТЬ: В хорошем ole 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 ]

6 голосов
/ 30 марта 2012

Если под "уникальными наборами" вы имеете в виду то, что я думаю, вы делаете (извините, я не знаю 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
;

"может этобыть выполненным без необходимости хранить элементы в таблице? .. т.е. позволить серверу сделать это, не прибегая к табличному вводу-выводу? "

Да, есть способ 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
;
5 голосов
/ 30 марта 2012

Если вы хотите включить пары одинаковых номеров, например (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;
3 голосов
/ 30 марта 2012

Не то, чтобы я на самом деле использовал базу данных для этого типа задач, но, если бы вас заставили делать это под угрозой пыток или расчленения, я бы посмотрел на что-то вроде (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).Если вы хотите комбинации (где порядок не имеет значения), вы должны использовать несколько другие предложения:

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 b.num > c.num and c.num > d.num and d.num > e.num
2 голосов
/ 30 марта 2012

Первая мысль о том, чтобы сделать декартову карту и просто убедиться, что каждая запись выше последней, чтобы вы никогда не дублировали числа.Теперь это создаст что-то вроде

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 

Если число МОЖЕТ получить повторяющиеся числа, просто измените равенство на <= вместопросто <. </p>

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
...