INNER JOIN 之前的 WHERE 子句

Posted

技术标签:

【中文标题】INNER JOIN 之前的 WHERE 子句【英文标题】:WHERE clause before INNER JOIN 【发布时间】:2012-04-25 09:02:03 【问题描述】:

如果我有

SELECT * FROM Table1 t1 
LEFT JOIN Table2 t2 ON t1.id = t2.id 
WHERE t1.user='bob';

WHERE 子句是否在两个表为JOINED 之后运行?

如何让它在 JOIN 之前运行?

【问题讨论】:

给出的答案是正确的,但值得深入研究。你为什么要寻找这种行为?我想查询优化器会为你处理明显的情况...... 【参考方案1】:

WHERE 更改为另一个JOIN 条件

LEFT JOIN Table2 t2 on t1.id = t2.id AND t1.user='bob'

【讨论】:

【参考方案2】:

你可以的

SELECT * 
    FROM Table1 t1 
    LEFT JOIN Table2 t2
        ON t1.id=t2.id AND t1.user='bob';

【讨论】:

【参考方案3】:

where 子句将在join 之前执行,这样它就不会加入不必要的记录。所以你的代码是好的。

【讨论】:

@user1124535 我可以确认。运行explain 查询,你会看到。 这是更好的答案。【参考方案4】:

根据我的左连接经验,您不能在 ON 语句中排除“左”(t1) 表中的记录,因为 - 根据定义 - 所有 t1 记录都将包括在内。 where 语句确实有效,因为它将应用于之后的连接结果。

我不完全知道您想要实现什么,但很可能内部连接也适合您的需求,然后您可以将 t1.user='bob' 条件添加到 ON 语句.

但如果 Mosty Mostacho 是正确的,则条件的位置(WHERE 与 ON)与执行速度无关。

【讨论】:

【参考方案5】:

RIGHT JOIN 是解决方案:

SELECT cars.manufacturer, cars.year FROM cars 
RIGHT JOIN (SELECT m.manufacturer FROM cars AS m ORDER BY m.year DESC LIMIT 3) subq 
ON cars.manufacturer=subq.manufacturer

还没有经过严格的测试,但似乎有效。

【讨论】:

【参考方案6】:

您应该在其他条件之前将t1.user='bob' 条件添加到ON 子句,它将首先被评估:

SELECT * FROM Table1 t1 
LEFT JOIN Table2 t2
ON t1.user='bob' AND t1.id = t2.id;

【讨论】:

【参考方案7】:

你可以使用 FROM 之后的表表达式,如下所示:

SELECT *
FROM (SELECT
        id
    FROM Table1
    WHERE user = 'bob') AS t1
LEFT JOIN Table2 t2
    ON t1.id = t2.id

【讨论】:

以上是关于INNER JOIN 之前的 WHERE 子句的主要内容,如果未能解决你的问题,请参考以下文章

带有 WHERE 子句的 SQL INNER JOIN 到 LINQ 格式

`INNER JOIN` 过滤条件在查询中的位置; `ON` 或 `WHERE` 子句 [关闭]

带有 WHERE 子句和 INNER JOIN 的 MySQL 更新查询不起作用

在 SQL Server 查询的 WHERE 子句中引用或 INNER JOIN 一个 Pandas 数据帧值 [重复]

MySQL内连接(INNER JOIN)

Oracle中Inner join和Where的区别