2

假设我们有两个表 Foo 和 Bar。我有一个关联表 Foo_Bar 用于 Foos 和 Bars 之间的多对多关系。

现在我基本上想要一个查询来选择与动态数量的 Bar 约束匹配的 Foos。我可以通过使用适当数量的连接动态生成查询来做到这一点:

SELECT *
FROM Foo F INNER JOIN
     Foo_Bar FB1 ON FB1.FooId = F.Id AND FB1.BarId= Y INNER JOIN
     Foo_Bar FB2 ON FB2.FooId = F.Id AND FB2.BarId= Z INNER JOIN
     --one inner join for each constraint

我想知道是否有更简单的方法。我基本上想要这样的查询:

SELECT *
FROM Foo F
WHERE (Y, Z, ...) IN (SELECT BarId FROM Foo_Bar WHERE FooId = F.Id)

当然,这不是有效的 SQL,但我想知道动态查询是否是实现所需结果的唯一合理可移植的方式。

4

2 回答 2

1

根据您提供的信息,以下查询将获取您需要的数据:

SELECT *
FROM Foo F INNER JOIN
     Foo_Bar FB ON FB1.FooId = F.Id
WHERE FB.BarId IN (Y, Z, ...)
于 2012-06-20T22:54:50.440 回答
1

我假设您想要一个关系除法查询。看到这个问题有很多方法可以做到这一点:How to filter SQL results in a has-many-through relationship

@Erwin 的答案(针对 Postrgres)中还有性能测试,您会注意到动态方式(使用许多联接或许多EXISTS子查询或许多IN子查询)比仅使用变量表或列表的静态查询执行得更快。

在您的服务器中进行测试,但要确定您的数据。例如,MySQL 在子查询方面存在一些性能问题IN,所以我希望它在JOIN不同版本中执行得更快。

这是在您的表格中翻译的“Erwin 1”查询:

SELECT f.*
FROM   Foo f
JOIN   (
   SELECT FooId 
   FROM   Foo_Bar
   WHERE  BarId IN (Y, Z, ...)               --- your list or table here
   GROUP  BY FooId
   HAVING COUNT(*) = @N                      --- the size of this list or table
   ) fb ON fb.FooId = f.Id;
于 2012-06-20T23:25:46.583 回答