以下是伪查询,所以我不关心结果,但是在以下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
仅为了HAVING
条件而被选中,因此结果中不需要其值。
查询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`
答案 0 :(得分:2)
总是在完成所有JOIN和WHERE过滤器后完成HAVING。它本质上是对查询结果的过滤器。这就是为什么你不能用它来过滤不属于查询的字段的原因。
您的查询将以不同方式执行。查询2将更有效,因为它将在JOIN期间过滤掉用户。查询1将与所有用户连接,提取所有数据并对其进行分组,然后按年龄对其进行过滤。查询2将GROUP和仅过滤12岁以下的用户,然后对其进行GROUP。需要在查询2中读取和分组较少的数据。
答案 1 :(得分:1)
您的查询完全不同。特别是,第二种是有效的标准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为NULL。在性能方面,所有这个版本都相当于你的第二个版本,而且这三个版本应该完全相同。