From my table with a single column of names I want to make a table with two columns where each row is a pair of names.
Input table:
name |
---|
ALICE |
BOB |
CHUCK |
Desired output table:
nameA | nameB |
---|---|
ALICE | BOB |
ALICE | CHUCK |
BOB | CHUCK |
2
You could use a recursive cte to get the expected result. The recursive cte uses row numbers of names sorted alphabeticaly. This is Inner Joined in unioned (recursive) part of the cte ON(n2.rn > n.rn) which ensures that you get all the combinations of current name with every name that is alphabeticaly after the current name…
WITH -- R e c u r s i v e C T E :
Recursive names ( pass, rn, name_1, name_2 ) AS
( Select 1, n.rn, n.name, n.name
From ( Select Row_Number() Over(Order By name) as rn, name
From tbl
) n
Union All
Select pass + 1, n.rn, n.name_1, n2.name
From names n
Inner Join ( Select Row_Number() Over(Order By name) as rn, name
From tbl
) n2 ON(n2.rn > n.rn)
Where n.pass < ( Select Count(*) From tbl )
)
… resultset gives you all combinations sorted and without oposite values (e.g. ALICE-BOB vs BOB-ALICE) …
/* Recursion ResultSet:
pass rn name_1 name_2
---- ---- ------ ------
1 1 ALICE ALICE
1 2 BOB BOB
1 3 CHUCK CHUCK
2 1 ALICE BOB
2 2 BOB CHUCK
2 1 ALICE CHUCK
3 1 ALICE BOB
3 1 ALICE BOB
3 1 ALICE CHUCK
3 2 BOB CHUCK
3 1 ALICE CHUCK */
… now just select distinct rows with different name_1 and name_2 …
-- M a i n S Q L :
Select Distinct name_1, name_2
From names
Where name_1 != name_2
Order By name_1
/*
name_1 name_2
------ ------
ALICE BOB
ALICE CHUCK
BOB CHUCK */
See the fiddle here.
… If you add another row in your table ( ‘MIKE’ ) the result of the code above should be …
/*
name_1 name_2
------ ------
ALICE BOB
ALICE CHUCK
ALICE MIKE
BOB CHUCK
BOB MIKE
CHUCK MIKE */