SQL,比较包含在多个链接表中的关系
我甚至很难解释这个问题 我有5张桌子,A,AZ,Z,BZ,B AZ表示a和Z之间的多对多关系。 BZ表示B和Z之间的多对多关系 我想要一个结果集,它是一个B,其中B链接到给定a的Z的完整集合 假设Z是一个标记表,包含:SQL,比较包含在多个链接表中的关系,sql,sql-server-2008,join,Sql,Sql Server 2008,Join,我甚至很难解释这个问题 我有5张桌子,A,AZ,Z,BZ,B AZ表示a和Z之间的多对多关系。 BZ表示B和Z之间的多对多关系 我想要一个结果集,它是一个B,其中B链接到给定a的Z的完整集合 假设Z是一个标记表,包含: Tag1 Tag2 Tag3 ObjectA ObjectB ObjectC WidgetX WidgetY WidgetZ ObjectA Tag1 ObjectA Tag2 ObjectB Tag3 ObjectC Tag2 ObjectC Tag3 Wid
Tag1
Tag2
Tag3
ObjectA
ObjectB
ObjectC
WidgetX
WidgetY
WidgetZ
ObjectA Tag1
ObjectA Tag2
ObjectB Tag3
ObjectC Tag2
ObjectC Tag3
WidgetX Tag1
WidgetX Tag2
WidgetY Tag2
WidgetY Tag3
WidgetZ Tag3
A是一个对象表,包含:
Tag1
Tag2
Tag3
ObjectA
ObjectB
ObjectC
WidgetX
WidgetY
WidgetZ
ObjectA Tag1
ObjectA Tag2
ObjectB Tag3
ObjectC Tag2
ObjectC Tag3
WidgetX Tag1
WidgetX Tag2
WidgetY Tag2
WidgetY Tag3
WidgetZ Tag3
B是一个小部件表,包含:
Tag1
Tag2
Tag3
ObjectA
ObjectB
ObjectC
WidgetX
WidgetY
WidgetZ
ObjectA Tag1
ObjectA Tag2
ObjectB Tag3
ObjectC Tag2
ObjectC Tag3
WidgetX Tag1
WidgetX Tag2
WidgetY Tag2
WidgetY Tag3
WidgetZ Tag3
AZ包含:
Tag1
Tag2
Tag3
ObjectA
ObjectB
ObjectC
WidgetX
WidgetY
WidgetZ
ObjectA Tag1
ObjectA Tag2
ObjectB Tag3
ObjectC Tag2
ObjectC Tag3
WidgetX Tag1
WidgetX Tag2
WidgetY Tag2
WidgetY Tag3
WidgetZ Tag3
BZ包含:
Tag1
Tag2
Tag3
ObjectA
ObjectB
ObjectC
WidgetX
WidgetY
WidgetZ
ObjectA Tag1
ObjectA Tag2
ObjectB Tag3
ObjectC Tag2
ObjectC Tag3
WidgetX Tag1
WidgetX Tag2
WidgetY Tag2
WidgetY Tag3
WidgetZ Tag3
我希望我的结果集为:
ObjectA WidgetX
ObjectB WidgetY
ObjectB WidgetZ
ObjectC WidgetY
这在查询中是可行的,还是我应该提取一些中间数据集并在代码中进行迭代?好的,根据您的反馈进行主要编辑以重新调整。这有点麻烦,但你看:
select distinct
x.aid,
x.bid
from
(select
az.aid,
bz.bid,
(select COUNT(1) from az az1 where az1.aid = az.aid) as acount,
(select COUNT(1) from bz bz1 where bz1.zid in (select zid from az az1 where az1.aid = az.aid) and bz1.bid = bz.bid) as bcount
from
az
inner join bz on
az.zid = bz.zid
) x
where
x.acount = x.bcount
它使用讨厌的子查询获得正确的计数,然后根据您的条件限制我们的行集。主要编辑:
正如安德烈正确地指出的那样,我在第一次尝试时就犯了错误。这应该做得更好:
select a, b.b
from az cross join b
left outer join bz on az.z = bz.z and b.b = bz.b
group by a, b.b
having sum(case when bz.b is null then 1 else 0 end) = 0
交叉连接建立了一个表,该表表示每个b满足AZ中每个a的条件的假设。左外部联接检查此假设,并在假设失败的bz.b列中保留空值。having子句排除包含一个或多个空值的a-b对。这不是正确的结果集。ObjectA链接到Tag1和Tag2。WidgetY未链接到Tag1,因此ObjectA对WidgetY无效。@JacobG-以后尝试使用更好的表名和实际数据,信不信由你,这些示例使帮助变得更加困难。@JacobG-好的,修正为正确的…让我知道这是否适用于你。@Eric-这是一个赢家。非常感谢!从我对这个问题的理解来看,为了使对象与小部件匹配,对象的标记集应该是小部件的子集。你的查询将返回太多的匹配项。+1,我昨天在放弃瞌睡之前正在考虑类似的问题。只有我在考虑交叉连接,从bz中选择不同的b,而不是b,但这不会影响结果,可能效率较低。+1这一个也有效。虽然它比Eric的解决方案慢几个数量级。这对我来说是个不错的策略。谢谢