何时向查询添加联接

时间:2014-04-25 14:22:08

标签: sql join where

背景

我们有一堆Java代码可以生成SQL查询。在为WHERE部分生成条件时,我们在引入必要的连接时遇到一些困难。 查询的目的始终是返回zoo的id(参见数据库结构)。

数据库结构

Image of the database structure

上下文

在UI中,用户单独定义过滤逻辑和WHERE子句片段。一个例子

  • 过滤逻辑:“1 OR(2 AND 3)OR(4 AND 5)”
  • WHERE子句:
    • 1:animal.name =“jack”
    • 2:zoo.city =“洛杉矶”
    • 3:animal.species =“bear”
    • 4:animal.species =“fish”
    • 5:animal.name =“henrietta”

问题

问题在于,根据过滤逻辑和WHERE子句块,可能需要额外的连接。当您有一个类似“(species = A AND name = B)AND(species = C AND name = D)”的查询时,至少需要新的连接(物种和名称列在进入时会与不同的值进行比较)和关系)。请注意,此查询仅有意义,因为它假设返回动物园的id,其中所有这些条件都为真。

所以我的问题是我不知道有多少连接是绝对必要的。我不知道我将得出答案的逻辑。因为如果您有像“(species = A OR species = B)”这样的查询,则不需要额外的连接。

预期行为

以下查询应返回所有动物园的ID,其中有两只动物名称为jack和tanya。

SELECT zoo.id FROM zoo
INNER JOIN animal a1 ON zoo.id = a1.zoo_id
INNER JOIN animal a2 ON zoo.id = a2.zoo_id
WHERE
a1.name = "jack"
AND a2.name = "tanya";

此查询说明需要两个连接。下一个例子说明只有一个连接就足够了。

SELECT zoo.id FROM zoo
INNER JOIN animal ON zoo.id = animal.zoo_id
WHERE
animal.name = "jack"
OR animal.name = "tanya";

天真的解决方案

最简单的解决方案是为每个动物表引用添加一个连接,但会产生严重的性能影响;与最小连接相比,增加了数千%。

2 个答案:

答案 0 :(得分:1)

对您所拥有的任何查询的此基线如下...

SELECT
      a.species,
      a.name,
      z.city
   from
      animals a
         join zoo z
            ON a.zoo_id = z.id

然后,只需将查询条件添加到WHERE子句中,例如

   where
          ( a.name = 'jack' )
      OR  ( a.species = 'bear' AND z.city = 'Los Angeles' )
      OR  ( a.species = 'fish' AND a.name = 'henrietta' )

它通过所有动物条目ONCE并拉出那些合格。我还有一个关于动物的索引(物种,名称),动物园表索引(id,city)

答案 1 :(得分:0)

您不需要额外的加入。

只需加入Zoo ID即可添加到语句的末尾" WHERE ...."

编辑:你在做什么"加入" ?如果是这样,请将过滤器从连接中取出,然后将其放在最后。