2014-09-24 118 views
0

我不知道这是否可能有相同的结果下面的请求不使用子查询选择:与WHERE NOT IN条件无子查询

SELECT p1.id 
FROM products p1 
WHERE NOT p1.id IN (
    SELECT p2.id 
    FROM products p2 
    JOIN product_translations t 
    ON t.product_id = p2.id 
    AND t.locale = 'fr' 
); 

正如你所看到的,products行可以有很多product_translations行(0..n)。

预期结果必须是只有没有product_translations且区域设置为fr的产品。

+0

你想这样做,没有一个子查询(尽管NOT EXISTS可能比NOT IN更快)为什么 – 2014-09-24 09:15:50

+0

SELECT p2.id FROM产品P2 LEFT JOIN product_translations吨 ON t.heroshop_record_id = p2.id AND t.locale = 'FR' WHERE t.heroshop_record_id为null – mhn 2014-09-24 09:16:54

+0

@a_horse_with_no_name完全相同,也可以是左连接到product_translations并通过使用IS 'product_translations'表上一列的NULL条件。 – 2014-09-24 09:17:55

回答

3

子查询中的连接是不需要的。因此,你的查询等于:

SELECT id 
FROM products 
WHERE id NOT IN 
(
    SELECT product_id 
    FROM product_translations 
    WHERE locale = 'fr' 
); 

没有一个子查询,你将不得不外连接转换表,消除比赛:

SELECT p.id 
FROM products p 
LEFT JOIN product_translations pt ON pt.product_id = p.id AND pt.locale = 'fr' 
WHERE pt.product_id IS NULL; 

编辑:只是为了完整起见这里是NOT EXISTS版本(也当然需要一个子查询):

SELECT id 
FROM products 
WHERE NOT EXISTS 
(
    SELECT * 
    FROM product_translations 
    WHERE product_id = products.id 
    AND locale = 'fr' 
); 
+0

我没那么想,谢谢!你知道哪一个将是最有效的? – louiscoquio 2014-09-24 09:33:49

+0

一个伟大的dbms会认识到NOT IN,NOT EXISTS和LEFT JOIN技术实际上在这里做同样的事情,并且会在内部总是使用相同的执行计划。 MySQL并不是那么棒。它以快速连接和IN子句缓慢而着称。但是,根据表格中记录的数量,匹配的数量以及是否存在适当的索引,这里可能会有所不同。你试一试。您也可以使用EXPLAIN来查看执行计划。 – 2014-09-24 09:38:45

+0

完美的解释,谢谢 – louiscoquio 2014-09-24 09:50:59