Search code examples
sqloracle-databaserecursioncombinationsfactorial

Oracle get all combinations possibilities with recursivity


I really need your help for an SQL request.

I have a table like this :

ID|LABEL|PRICE
1 |A    |10
2 |B    |15
3 |C    |20
4 |D    |30
5 |E    |35

I want to get all combinations possibilies with an sql request (or pl/sql procedure) likes this :

A, AB, AC, AD, AE, ABC, ABD, ABE, AC, ABCD, ABCE, ABCDE... DE, BDE, CE...

Each label can appear only one time, for example, ABA is not possible, i think it's like a factorial mathematical function?

I try with "start with" "connect by" but I don't understand how to correctly use it.

Do you have an idea to get this?

Thanks for your help.

Charles


Solution

  • Try this query

    select sys_connect_by_path( label, ';' )
    from table1
    connect by nocycle label <> prior label
    ;
    

    or this one:

    select sys_connect_by_path( label, ';' )
    from table1
    connect by nocycle label > prior label
    ;
    

    ========== EDIT==========


    To get a sum of prices, you can use a subquery factoring clause, in this way:

    WITH abc( label, pricesum, pricelist, lastlabel) AS (    
         SELECT label, 
                price, 
                cast( price as varchar2(1000)), 
                label    
         FROM table1    
         UNION ALL    
         SELECT a.label || ';' || b.label, 
                a.price + b.price, 
                a.pricelist|| '+'||b.price , 
                b.label    
         FROM abc a    
         JOIN table1 b    
         ON b.label > a.lastlabel 
    ) CYCLE label SET cycle TO 1 DEFAULT 0 
    SELECT * FROM abc;
    

    The third column pricelist shows a list of all prices thar are being summed,
    for example:

    label pricesum pricelist  lastlabel
    A       10     10           A   0
    B       15     15           B   0
    A;B     25     10+15        B   0
    A;C     30     10+20        C   0
    A;D     40     10+30        D   0
    A;C;D   60     10+20+30     D   0
    A;C;E   65     10+20+35     E   0
    A;B;D;E 90     10+15+30+35  E   0
    A;C;D;E 95     10+20+30+35  E   0
    B;C;D;E 100    15+20+30+35  E   0