- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想知道为什么这个查询仍然可以完美运行。我认为 WHERE 子句总是必须以 WHERE
开头?
SELECT `persons`.*
FROM `persons`
LEFT JOIN `team_memberships`
ON (`team_memberships`.`participant` = `persons`.`id`)
JOIN `teams`
ON (`teams`.`id` = `team_memberships`.`team`)
JOIN `departments`
ON (`departments`.`id` = `teams`.`department`)
JOIN `areas`
ON (`areas`.`id` = `departments`.`area`)
JOIN `companies`
ON (`companies`.`id` = `areas`.`company`)
[NO WHERE HERE]
AND `persons`.`id` = ?
最佳答案
您刚刚在 ON
子句中添加了一个 AND
。 ON
子句的计算结果为 bool 值 true 或 false,因此 AND
和例如 OR
bool 运算符是允许的,具有关于括号等也适用。
将特定于特定联接表的条件从 WHERE
子句移动到适当的 ON
子句通常是有利的 - 如果没有其他原因提高可读性。
在 继续连接其他表之前限制连接的结果是合乎逻辑的*有意义的,而不是返回一个大的结果集,然后在最后用 WHERE
子句。我说 *合乎逻辑,因为 DBMS 通常会优化您的查询,以便无论如何都会发生这种情况......但并非总是如此......有时可以通过在连接处进行过滤来改进性能不佳的查询(有时反之亦然)。
例如,如果您知道自己只对 25 岁以上的人感兴趣,那么JOIN persons ON persons.id = team_memberships.participant AND persons.age > 25
是有意义的,而不是包括 所有 仅与年轻朋克有关的后续表格的结果,只是在末尾使用您的 WHERE persons.age > 25
子句再次过滤这些结果。
我的理解是,连接性能可能会因 ON
子句中的附加表达式而降低,在附加表达式的实例中:
导致对联接中的每一行进行评估(因此我上面的 age > 25
示例可能属于此类),或者
依赖一个/两个连接表中的非索引列,否则连接将仅依赖于索引列。
因此,例如,在连接时从结果集中剥离年轻朋克可能仍然值得,即使这会使特定连接变慢,因为此时较小的结果集可能会大大提高后续连接的性能。但是,如果将它们包含在联接中只会使记录数量略有增加,那么实际上将它们包含在联接中然后在 WHERE
子句中将它们过滤掉实际上可能会更快。
但我欢迎评论澄清/纠正我的理解。
编辑:根据下面的@ITroubs 评论,我真的应该澄清一下,如果连接是 INNER JOIN
,那么无论附加过滤条件是否在ON
或 WHERE
子句,但例如在 OP 的原始示例中,如果移动过滤条件,LEFT JOIN ON team_memberships
将产生完全不同的结果集从 WHERE
到 LEFT JOIN ... ON ...
。
关于php - 特殊行为 : AND without WHERE still works,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15526985/
我是一名优秀的程序员,十分优秀!