长话短说,我应该在GROUP BY子句之后添加哪些字段?
SELECT questions.question_id, questions.title, questions.content, questions.view_count, questions.posted_on, users.user_id, users.group_id, users.username, users.first_name, users.last_name COUNT(answers.answer_id) AS answer_count
FROM (questions)
JOIN answers ON questions.question_id = answers.question_id
JOIN users ON questions.user_id = users.user_id
WHERE `questions`.`publish` = 'Y' AND `questions`.`deleted_at` IS NULL AND `users`.`blocked` = 'N'
GROUP BY questions.question_id
我应该把SELECT中提到的每个非聚合字段,或只是其中一个是好的? (例如,只是question_id)我很困惑,因为无论哪种方式,结果都是一样的。有什么区别?
所有在网上的教程似乎只提供了一个使用两个字段的例子,一个聚合字段和一个普通字段。更新:好吧,看起来我必须把所有这些都放到一起来获得准确的结果。这引出了其他问题:准确度如何准确?一个人不会做得好吗?对绩效的影响如何?
答案 0 :(得分:1)
您需要将所有非聚合列放在准确的结果中。
答案 1 :(得分:1)
“您需要将所有非聚集列放在准确的结果中”
是的,但我想补充一点,你按照你想要的顺序排列所有列(这对你来说很重要吗?)。
编辑:准确意味着如果您不这样做,您的查询就会崩溃。关于表演,你的GROUP BY中的领域越多,你的表现越少,但这并不是一个惊喜
答案 2 :(得分:1)
MySQL接收这两个选项,其他数据库则不接收。 其他数据库(hsqldb,Oracle)将强制您将所有选定的字段放在GROUP BY子句中。 当一个人将所有列放在GROUP BY子句之后时,结果通常不那么模糊。 MySQL将您的查询“解释”为:
SELECT questions.question_id, FIRST_VALUE(questions.title), FIRST_VALUE(questions.content), FIRST_VALUE(questions.view_count), FIRST_VALUE(questions.posted_on), FIRST_VALUE(users.user_id), FIRST_VALUE(users.group_id), FIRST_VALUE(users.username), FIRST_VALUE(users.first_name), FIRST_VALUE(users.last_name) COUNT(answers.answer_id) AS answer_count
FROM (questions)
JOIN answers ON questions.question_id = answers.question_id
JOIN users ON questions.user_id = users.user_id
WHERE `questions`.`publish` = 'Y' AND `questions`.`deleted_at` IS NULL AND `users`.`blocked` = 'N'
GROUP BY questions.question_id
即如果MySQL具有“FIRST_VALUE”功能。
因为您按唯一标识符(questions.question_id)进行分组,结果是相同的。 如果按非唯一标识符分组,则返回的值非常不明确。
我唯一不确定的是,根据单个字段进行组的效率是否更高。我的猜测是,DB足够聪明,可以理解你是按照唯一标识符进行分组,并相应地计划执行,但我不确定。
如果效率没有差异 - 您应该将所有字段放在GROUP BY之后,因为它更标准。否则,决定是否优先编写标准SQL而不是编写高效的SQL。
答案 3 :(得分:0)
(即所有这些)
或
你可以有另一个内部联接计数,所以你只需要做一个。
编辑:这是第二个选项的示例(尚未测试,但应该有效)
SELECT questions.question_id, questions.title, questions.content, questions.view_count, questions.posted_on, users.user_id, users.group_id, users.username, users.first_name, users.last_name, r.AN_ANSWER_COUNT
FROM (questions q)
JOIN answers ON questions.question_id = answers.question_id JOIN users ON questions.user_id = users.user_id
left join (SELECT question_id, COUNT(a.answer_id) AS AN_ANSWER_COUNT
FROM answers a
WHERE (your_condition)
GROUP BY question_id)r
on q.question_id = a.question_id
WHERE `questions`.`publish` = 'Y' AND `questions`.`deleted_at` IS NULL AND `users`.`blocked` = 'N'