MySQL中的分组连接查询-使用ON与具有过滤条件(有什么区别?)
以下是伪查询,所以我不关心结果,但是以下MySQL查询之间有什么不同(在性能、结果量等方面) 查询1MySQL中的分组连接查询-使用ON与具有过滤条件(有什么区别?),mysql,join,filtering,Mysql,Join,Filtering,以下是伪查询,所以我不关心结果,但是以下MySQL查询之间有什么不同(在性能、结果量等方面) 查询1 SELECT u.`username`, COUNT(*) AS 'posts', u.`age` FROM `users` u INNER JOIN `posts` p ON p.`user_id`=u.`id` GROUP BY u.`id` HAVING u.`age` > 12 假设此查询中的列smth仅为具有条件而选择,因此结果中不需要该列的值 查询2 SELECT u.`us
SELECT u.`username`, COUNT(*) AS 'posts', u.`age`
FROM `users` u
INNER JOIN `posts` p
ON p.`user_id`=u.`id`
GROUP BY u.`id`
HAVING u.`age` > 12
假设此查询中的列smth
仅为具有
条件而选择,因此结果中不需要该列的值
查询2
SELECT u.`username`, COUNT(*) AS 'posts'
FROM `users` u
INNER JOIN `posts` p
ON p.`user_id`=u.`id` AND u.`age` > 12
GROUP BY u.`id`
你的问题完全不同。特别是,第二个是有效的标准SQL语法。第一个使用MySQL特性,允许在聚合中允许任何列 特别是,第一个查询中的列
smth
来自匹配数据中的任意行。如果所有行上的所有值都相同,则使用这两个值的结果将是等效的
如果我假设u.id对于用户中的每一行都是唯一的,那么结果集是等价的。但是,我认为SQL的更具可读性的版本是:
SELECT u.`username`, COUNT(*) AS 'posts', u.`smth`
FROM `users` u INNER JOIN
`posts` p
ON p.`user_id`=u.`id`
WHERE u.smth is not null
GROUP BY u.`id`, u.username
HAVING u.`smth` IS NOT NULL
这清楚地表明,您希望每行上有一个单独的用户名,并且不希望smth为空。就性能而言,所有此版本与您的第二个版本相当,并且所有三个版本应该基本相同。始终在所有联接之后以及在完成筛选器的位置执行have。它本质上是查询结果的过滤器。这就是为什么不能使用它对不属于查询的字段进行筛选
您的查询将以不同的方式执行。查询2会更有效,因为它会在加入过程中过滤掉用户。查询1将加入所有用户,提取所有数据并对其进行分组,然后根据年龄对其进行过滤。查询2将仅对12岁以下的用户进行分组和筛选,然后对其进行分组。查询2中需要读取和分组的数据会减少。很难说(也许是不相关的),因为您的查询实际上没有意义。您返回的列既不是聚合的,也不是按查询分组的。为什么不在
WHERE
子句中设置u.`smth`
条件?@GiantofaLannister聚合将使其不可能。对查询运行explain
,看看mysql是怎么说的。@KeithRandall没有任何区别。感谢您的帮助澄清这很有道理。