Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL中的分组连接查询-使用ON与具有过滤条件(有什么区别?)_Mysql_Join_Filtering - Fatal编程技术网

MySQL中的分组连接查询-使用ON与具有过滤条件(有什么区别?)

MySQL中的分组连接查询-使用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

以下是伪查询,所以我不关心结果,但是以下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.`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没有任何区别。感谢您的帮助澄清这很有道理。