SQL Server Find unique combination of column values in SQL

rdlzhqv9  于 2023-10-15  发布在  其他
关注(0)|答案(2)|浏览(120)

I am trying to find all the unique possible combinations of values in a column using SQL.

I have a table with a maximum of 5 values in a single column: something like:

a,
b,
c,
d,
e

I need help with a my SQL Server code to find only the UNIQUE combinations of the values which would be:

ab, ac, ad, ae, bc, bd, be, cd, ce, de, abc, acd, ade...

Currently I am using the below code to find the 1,2 value combinations. The table name is my_table and the column with the values is non_unique_column .

select 
    RANK() OVER (PARTITION BY '' ORDER BY concat(col1,col2,col3)) [index]
    ,* into final_comb_out 
from (select 
            non_unique_column col1, NULL as col2,NULL AS COL3 FROM my_table 
        UNION ALL
        SELECT DISTINCT LEAST(t1.non_unique_column, t2.non_unique_column) AS value1,
                GREATEST(t1.non_unique_column, t2.non_unique_column) AS value2
                ,NULL AS value3    
        FROM my_table t1
CROSS JOIN my_table t2
WHERE t1.non_unique_column <> t2.non_unique_column

The issue with this code is that the LEAST and GREATEST function are not supported by the client system and cannot be included.

I would very much appreciate code that could help me out here. Thanks.

mpbci0fu

mpbci0fu1#

You can use recursion:

WITH RecursiveCombination AS (
    SELECT 
        CAST(non_unique_column AS VARCHAR(255)) AS combination,
        non_unique_column AS last_char
    FROM my_table
    UNION ALL
    SELECT 
        CAST(rc.combination + mt.non_unique_column AS VARCHAR(255)) AS combination,
        mt.non_unique_column AS last_char
    FROM my_table mt
    JOIN RecursiveCombination rc ON mt.non_unique_column > rc.last_char
)
SELECT combination
FROM (
    SELECT DISTINCT combination, LEN(combination) as len_comb
    FROM RecursiveCombination
    WHERE LEN(combination) > 1
) t
ORDER BY t.len_comb, t.combination;

Output:

combination
ab
ac
ad
ae
bc
bd
be
cd
ce
de
abc
abd
abe
acd
ace
ade
bcd
bce
bde
cde
abcd
abce
abde
acde
bcde
abcde

Try it out here.

uubf1zoe

uubf1zoe2#

The fixed max length of the source table allows a plain join solution, e.g.

declare @x char(1)=char((select ascii(max(non_unique_column))+1 from my_table)); 
with tplus as (
  select * from my_table union select @x
)
select comb
from (
    select replace(
       cast(t1.non_unique_column AS VARCHAR(5)) 
          + t2.non_unique_column 
          + t3.non_unique_column 
          + t4.non_unique_column
          + t5.non_unique_column
                    ,@x,'') comb
    from my_table t1
    join my_table t2 on t1.non_unique_column < t2.non_unique_column
    join tplus t3 on t2.non_unique_column < t3.non_unique_column
    join tplus t4 on t3.non_unique_column < t4.non_unique_column or t4.non_unique_column = @x
    join tplus t5 on t4.non_unique_column < t5.non_unique_column or t5.non_unique_column = @x
) t
order by len(comb), comb

db<>fiddle

Still I'd prefer a recursive one as Sash Sinha suggested.

相关问题