问题
given table:
create table Person( Name varchar(100) )
where Name is unique for all Persons
What SQL query can generate all possible n!/((n-2)!2!) round robin combinations?
It is assumed that the cardinality of Person is ALWAYS equal to 4
Example Person = {'Anna','Jerome','Patrick','Michael')
Output:
Anna, Jerome
Anna, Patrick
Anna, Michael
Jerome, Patrick
Jerome, Michael
Patrick, Michael
Any help would be appreciated. Thanks!
Here's my answer (I used oracle SQL):
select P1.NAME PERSON1, P2.NAME PERSON2
from (select rownum RNUM, NAME
from PERSON) P1,
(select rownum RNUM, NAME
from PERSON) P2
where P1.RNUM < P2.RNUM
回答1:
Here are two solutions for the problem
SELECT t1.Name + ',' + t2.Name AS NamesCombination
FROM Person t1
INNER JOIN Person t2
ON t1.Name < t2.Name
OR (Oracle 11i R2+)
WITH NamesCombination AS
(
SELECT 1 AS Cntr
,Name
, CAST(Name AS VARCHAR(MAX))AS NamesCombinations
FROM Person
UNION ALL
SELECT
nc.Cntr+1
,p.Name
,nc.NamesCombinations + ',' + CAST(p.Name AS VARCHAR(MAX))
FROM Person AS p JOIN NamesCombination nc ON p.Name < nc.Name
WHERE nc.Cntr < 2
)
SELECT NamesCombinations
FROM NamesCombination
WHERE Cntr = 2
回答2:
select P1.NAME PERSON1, P2.NAME PERSON2
from (select rownum RNUM, NAME
from PERSON) P1,
(select rownum RNUM, NAME
from PERSON) P2
where P1.RNUM < P2.RNUM
回答3:
Note that this is TSQL (Sql Server) syntax. I know that Oracle supports windowing functions, particularly row_number(), which is necessary for this solution.
It shouldn't be too hard to get this to work in Oracle with some trial and error
select p1.name, p2.name
from
(
select name, row_number() over(order by name) as rownumber
from person
) p1
inner join
(
select name, row_number() over(order by name) as rownumber
from person
) p2
on p1.name <> p2.name
and p1.rownumber > p2.rownumber
order by 1
row_number assigns a row number to each row. You then need to join, as suggested before, with the additional join clause of p1.rownumber > p2.rownumber
来源:https://stackoverflow.com/questions/13372232/sql-all-possible-round-robin-combinations-between-two-tables