假设我们有两张表 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,但我想知道动态查询是否是实现所需结果的唯一合理可移植的方式。
最佳答案
我假设您想要一个关系除法查询。看到这个问题有很多方法可以做到这一点:How to filter SQL results in a has-many-through relation
@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;
关于查询中的 SQL 动态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11129306/