在SQL中生成所有可能的组合?

问题描述

我有一个一个成分,其列为 Name

Name
________
Cheese
Beans
Potato
etc

我想在两个列中显示这些值的所有可能组合,例如(奶酪,豆类)(奶酪,马铃薯),(豆类,马铃薯)等。这可能吗?

desired result

解决方法

使用交叉联接:

SELECT t1.Name,t2.Name
FROM yourTable t1
CROSS JOIN yourTable t2
WHERE t1.Name <> t2.Name;   -- use t1.Name < t2.Name if you don't want
                            -- a given pair appearing in reverse

screen capture from demo link below

Demo

这将生成名称的所有可能组合,唯一的限制是我们不会重复报告同一名称两次。

,

这是一种自我加入:

select t1.name name1,t2.name name2
from ingredients t1
inner join ingredients t2 on t2.name > t1.name

存在不平等条件是为了确保我们不会生成“镜像”记录(例如“奶酪/豆子”与“豆子/奶酪”)。

如果要镜像记录,请将其更改为t2.name <> t1.name

如果您还想要“重复”记录(例如“奶酪/奶酪”),请改用cross join

,

使用自我加入

select i1.ingredient,i2.ingredient
from ingredients i1 join
     ingredients i2
     on i1.ingredient < i2.ingredient;

对于四种成分,这将返回6行,所有可能的对中,每对仅出现一次。

注意:这假设您不希望重复。如果要所有对,其中相同的成分可以以任意顺序出现在两列中,请使用cross join

select i1.ingredient,i2.ingredient
from ingredients i1 cross join
     ingredients i2;
,

交叉联接将为您提供想要的东西。

FROM tableName t1
CROSS JOIN tableName t2;

交叉连接为您提供了所有可能的组合。

,

可以通过多种方式来实现。我会按照已经建议的那样进行交叉连接,因为我认为这看起来更加清楚。 您还可以将表与其名称不相等的自身连接起来。

declare @t table (name varchar(50))

insert into @t
values('a'),('b'),('c'),('d'),('e'),('f')

select * from @t t1 join @t t2
on t1.name <> t2.name