47

How do I return a list of all combinations of values in 2 columns so they are new rows in T-SQL?

e.g.

Col1, Col2
----  ----
1     2
1     4
1     5

and turn this into all combinations:

1     2
1     4
1     5
2     4
2     5
4     5
2
  • 1
    What do you mean by new rows? What are the rules for combining? Is 1,1 valid or not? Commented Dec 7, 2010 at 16:04
  • The 3 original rows are within a table and they need to be expanded out using a select statement. Commented Dec 7, 2010 at 16:14

8 Answers 8

51

Assuming at least SQL 2005 for the CTE:

;with cteAllColumns as (
    select col1 as col
        from YourTable
    union
    select col2 as col
        from YourTable
)
select c1.col, c2.col 
    from cteAllColumns c1 
        cross join cteAllColumns c2 
    where c1.col < c2.col
    order by c1.col, c2.col
Sign up to request clarification or add additional context in comments.

1 Comment

As per the comments in @BobBlack's answer, this is the accepted solution because it avoids repeating 1-2 and 2-1 etc. (i.e. the results are an unordered set)
49

You could cartesian join the table to itself, which would return all combinations of both columns.

select 
    distinct
    t1.Col1,
    t2.Col2
from 
    MyTable t1,
    MyTable t2

4 Comments

Add "select distinct" and you've got it.
I've tried this but I need Col 2 values in Col 1 so they are swapped round. I thought unpivot might help but not really sure...
@Jon - are you saying you need Col2 to be displayed first, before Col1, in the resultset? Not quite sure what the issue is.
@Sir Wobin: The issue is that I need to return all unique combinations. 1-2 is the same as 2-1 so can be ommitted. The CTE with swapped columns unioned and then cross joined seems to do the trick (see above solution).
20

You can do a self cross join...

SELECT a.Col1, b.Col2
FROM MyTable a
CROSS JOIN MyTable b

2 Comments

Why isn't this answer more popular? Is there something wrong?
This needs SELECT DISTINCT I think. Also, although this is useful it doesn't do what the OP wants which is all combinations of both columns!
9

I was looking for something that would do this using only the SQL available to Microsoft Access 2016. I ended up figuring out something that others may find useful. This code utilizes CROSS JOIN so I found that it is necessary to split the two columns into two separate tables (each with one column). The AND statement forces one column to be less than the other, thereby eliminating any repetitive 1-2, 2-1 sort of occurrences.

SELECT DISTINCT Table1.Column1, Table2.Column1
FROM Table1, Table2
WHERE Table1.Column1 <> Table2.Column1
AND Table2.Column1 < Table1.Column1;

1 Comment

Hi Josh, welcome to Stack Overflow! New users often write pretty bad answers. Congratulations for putting in the effort of explaining why your solution might be better suited for some readers. +1 for that!
4

I think this has been over complicated! Just:

SELECT distinct Col1, Col2
FROM MyTable

to get all possible combinations..

4 Comments

This query ran in an instant for me - it returned all possible combinations of two fields in my table. The other queries timed out. I hope it helps others, like you helped me identify my shortcomings.
This solution is excellent, worked like a charm for me and was very simple. Never feel bashful about adding a potentially better solution to an already answered question.
This solution returns both columns from all rows, but not all combinations of both columns.
This is not a generic solution, but a specialized one that works only when the data is arranged in a certain way.
1

This uses 2 cte's, the first simply reproduces your input table, the second turns both columns into a single column. The final select crossjoin's this set to itself to produce the required output

with t(c1,c2)
AS
(
    select 1,2
    union select 1,4
    union select 1,5
)
,t2(c)
as
(
    select c1 from t
    union select c2 from t
)
select t2_1.c, t2_2.c
from t2 t2_1 
cross join t2 t2_2
where t2_1.c<t2_2.c
order by t2_1.c

Comments

-1

I find an inner join more intuitive because I use it more frequently than a cross join:

;with cteAllColumns as (
select col1 as col
    from YourTable
union
select col2 as col
    from YourTable
) 

select c1.col, c2.col 
from cteAllColumns c1 
    join cteAllColumns c2 on 1=1
where c1.col < c2.col
order by c1.col, c2.col

Comments

-1

Making Joe Answer easier

declare @t1 table  (col1 varchar(5))
insert @t1 
    select 'A' UNION
    select 'B' UNION
    select 'C' 


declare @t2 table  (col2 varchar(5))
insert @t2
    select '1' UNION
    select '2' UNION
    select '3' 


;with cteAllColumns as (
    select col1 as col
        from @t1
    union
    select col2 as col
        from @t2
)
select c1.col, c2.col 
    from cteAllColumns c1 
        cross join cteAllColumns c2 
    where c1.col < c2.col
    order by c1.col, c2.col

verify your combinations Qty (No of rows) http://www.calculatorsoup.com/calculators/discretemathematics/combinations.php

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.