Комбинации из одной таблицы, сгруппированные по значению столбца - PullRequest
0 голосов
/ 28 марта 2019

У меня есть таблица значений:

+-----+-------+
| ID  | STATE |
+-----+-------+
|  1  |   AL  |
|  1  |   AZ  |
|  1  |   MI  |
|  2  |   TX  |
|  2  |   TN  |
|  2  |   MO  |
|  2  |   ND  |
And many, many more...

Как мне написать запрос, который генерирует все возможные комбинации состояний для каждого отдельного идентификатора? Таким образом, результаты как:

+-----+-------------+
| ID  | COMBINATION |
+-----+-------------+
|  1  | AL, AZ      |
|  1  | AL, MI      |
|  1  | AZ, MI      |
|  1  | AL, AZ, MI  |
|  2  | TX, TN      |
|  2  | TX, MO      |
|  2  | TX, ND      |
|  2  | TN, MO      |
|  2  | TN, ND      |
  And so on...

Спасибо за помощь!

РЕДАКТИРОВАТЬ: Равшан заставил меня думать, что я не хочу перестановок, но бонус, если строка комбинации в алфавитном порядке.

1 Ответ

2 голосов
/ 28 марта 2019

Вы можете сделать это, используя иерархические запросы - вот один из них, использующий старый стиль connect by:

WITH your_table AS (SELECT 1 ID, 'AL' state FROM dual UNION ALL
                    SELECT 1 ID, 'AZ' state FROM dual UNION ALL
                    SELECT 1 ID, 'MI' state FROM dual UNION ALL
                    SELECT 2 ID, 'TX' state FROM dual UNION ALL
                    SELECT 2 ID, 'TN' state FROM dual UNION ALL
                    SELECT 2 ID, 'MO' state FROM dual UNION ALL
                    SELECT 2 ID, 'ND' state FROM dual UNION ALL
                    SELECT 3 ID, 'OH' state FROM dual)
SELECT ID,
       state,
       ltrim(SYS_CONNECT_BY_PATH(state, ','), ',') combinations,
       LEVEL
FROM   (SELECT id,
               state,
               count(*) OVER (PARTITION BY id) state_cnt
        FROM your_table)
WHERE  state_cnt = 1
OR     (state_cnt > 1 AND LEVEL > 1)
CONNECT BY PRIOR ID = ID
           AND PRIOR state < state
           AND PRIOR sys_guid() IS NOT NULL;

        ID STATE COMBINATIONS      LEVEL
---------- ----- ------------ ----------
         1 AZ    AL,AZ                 2
         1 MI    AL,AZ,MI              3
         1 MI    AL,MI                 2
         1 MI    AZ,MI                 2
         2 TX    TN,TX                 2
         2 TX    MO,TX                 2
         2 TN    MO,TN                 2
         2 TX    MO,TN,TX              3
         2 ND    MO,ND                 2
         2 TX    MO,ND,TX              3
         2 TN    MO,ND,TN              3
         2 TX    MO,ND,TN,TX           4
         2 TX    ND,TX                 2
         2 TN    ND,TN                 2
         2 TX    ND,TN,TX              3
         3 OH    OH                    1

Условие prior sys_guid() is not null в предложении connect by требуется, чтобы убедиться, что мы зациклим правильные строки (если вы его опустите, результат будет содержать много дополнительных строк).

Я исключил строки только с одним состоянием в выводе - за исключением того, что идентификатор указывал только одно состояние. Вы можете включать или не включать отдельные состояния в выходные данные, и в этом случае вы можете полностью удалить предикаты.

...