如何在没有IN关键字的情况下重写此查询?

时间:2012-01-20 11:26:14

标签: mysql

我写了这个查询:

SELECT * 
FROM etape_prospection INNER JOIN type_prospection 
ON etape_prospection.type_prosp_id = type_prospection.type_prosp_id 
WHERE etape_prospection.prosp_id IN (select transfert.prosp_id 
                                     from transfert 
                                     where transfert.user_code ='3' 
                                     AND transfert.date_transfert='2012-01-20');

我的老板不喜欢这个查询,因为IN关键字会进行全表扫描,那么如何在没有IN关键字的情况下重写它?

5 个答案:

答案 0 :(得分:1)

尝试

SELECT * 
FROM etape_prospection INNER JOIN type_prospection 
ON etape_prospection.type_prosp_id = type_prospection.type_prosp_id inner join transfert 
on etape_prospection.prosp_id = transfert.prosp_id 
where transfert.user_code ='3'  AND transfert.date_transfert='2012-01-20'

答案 1 :(得分:1)

您可以使用EXISTS代替IN这通常比IN便宜,有时也比其他答案中建议的INNER JOIN便宜:

SELECT * 
FROM etape_prospection INNER JOIN type_prospection 
ON etape_prospection.type_prosp_id = type_prospection.type_prosp_id 
WHERE EXISTS (select 1
               FROM transfert 
               WHERE transfert.prosp_id = etape_prospection.prosp_id
               AND transfert.user_code ='3' 
               AND transfert.date_transfert='2012-01-20');

另外(danihp在one of the other answers上的评论提醒):如果INNER JOIN中有多行,则使用transfert可能会导致在结果集中重复行的不必要/无意的副作用满足这些条件。

答案 2 :(得分:0)

使用另一个内部联接

SELECT etape_prospection.*,type_prospection.*
FROM etape_prospection 
INNER JOIN type_prospection 
  ON etape_prospection.type_prosp_id = type_prospection.type_prosp_id 
INNER JOIN transfert 
  ON etape_prosection.pros_id = transfert.prosp_id
WHERE transfert.user_code ='3' 
  AND transfert.date_transfert='2012-01-20';
Group BY transfert.pros_id

还更改了SELECT以不显示transfert列

答案 3 :(得分:0)

我认为这应该有效:

        SELECT * 
          FROM etape_prospection 
    INNER JOIN type_prospection ON etape_prospection.type_prosp_id = type_prospection.type_prosp_id 
    INNER JOIN transfert on transfert.prosp_id = etape_prospection.prosp_id 
         WHERE transfert.user_code ='3' 
           AND transfert.date_transfert='2012-01-20';

然而,IN实际上并不总是提供全表扫描,我怀疑你错过了索引。 in子句具有几乎固定的执行时间的好处,而添加额外的连接将使查询依赖于transfert表的基数(n°的元组)。

答案 4 :(得分:0)

这个怎么样:

SELECT * FROM etape_prospection 
INNER JOIN type_prospection ON etape_prospection.type_prosp_id = type_prospection.type_prosp_id  
LEFT JOIN transfert ON transfert.prosp_id = etape_prospection.prosp_id
WHERE transfert.user_code ='3' AND transfert.date_transfert='2012-01-20';