将WHERE子句中的相关子查询写为连接

时间:2013-06-14 07:22:58

标签: sql

我有如下查询:

select 
  a.id, a.title, a.description
from
  my_table_name as a
where
  a.id in (select id from another_table b where b.id = 1)

我的问题是,有什么方法可以避免where子句中的子查询并在from子句中使用它而不影响性能?

3 个答案:

答案 0 :(得分:3)

到目前为止给出的两个答案在一般情况下都是不正确的(尽管数据库可能有唯一的约束条件,以确保它们在特定情况下是正确的)

如果another_table可能包含多个具有相同id的行,则INNER JOIN将带回IN版本中不存在的重复项。如果DISTINCT中的列本身具有重复项,则尝试使用my_table_name删除它们可能会更改语义。

一般的重写是

SELECT a.id,
       a.title,
       a.description
FROM   my_table_name AS a
       JOIN (SELECT DISTINCT id
             FROM   another_table
             WHERE  id = 1) AS b
         ON b.id = a.id 

此重写的性能特征取决于实现。

答案 1 :(得分:2)

您可以将INNER JOIN用作:

select 
  a.id, a.title, a.description
from
  my_table_name as a INNER JOIN another_table as b ON (a.id = b.id and b.id = 1)

或者

select 
  a.id, a.title, a.description
from
  my_table_name as a INNER JOIN another_table as b ON a.id = b.id
where b.id = 1
  

两个查询都可能不会为您返回相同的值。你可以选择适合自己的东西。请将此作为起点,而不是复制粘贴代码。

答案 2 :(得分:2)

将其表达为联接:

select distinct
  a.id, a.title, a.description
from my_table_name as a
join another_table b on b.id = a.id
where b.id = 1

使用distinct是为了产生相同的结果,以防another_table具有多次相同的id,因此同一行不会多次返回。

注意:如果my_table_name中的id,name和description的组合不唯一,则此查询将不会返回原始查询所包含的重复项。


为了保证产生相同的结果,您需要确保another_table中的id是唯一的。要以联接方式执行此操作:

select
  a.id, a.title, a.description
from my_table_name as a
join (select distinct id from another_table) b on b.id = a.id
where b.id = 1