MySQL 5.7.24 COUNT() 无法与 sql_mode=only_full_group_by 一起正常工作
MySQL 5.7.24 COUNT() does not work correctly with sql_mode=only_full_group_by
我正在尝试找出在一个查询中 returning posts 和用户的 posts 总数的适当方法。
因此,计算用户 post 总数的最简单方法是:
SELECT COUNT(id) as total FROM posts WHERE uID = 37;
+-------+
| total |
+-------+
| 10 |
+-------+
接下来,我将查询更改为 return post 的 ID,并将总结果限制为前 5 个 post。但是 MySQL 抛出错误 1140...
SELECT id, COUNT(id) as total FROM posts WHERE uID = 37 LIMIT 0,5;
Error Code: 1140. In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'db.posts.id'; this is incompatible with sql_mode=only_full_group_by
好的,没有难过的感觉...我不打算更改默认值 'sql_mode' 所以我通过添加 GROUP BY
子句来修复上述错误按照建议进行查询,但现在 COUNT()
函数没有多大意义,因为每个结果 returns 1...嗯
SELECT id, COUNT(id) as total FROM posts WHERE uID = 37 GROUP BY id LIMIT 0,5;
+----+-------+
| id | total |
+------------+
| 1 | 1 |
+----+-------+
| 2 | 1 |
+----+-------+
| 3 | 1 |
+----+-------+
| 4 | 1 |
+----+-------+
| 5 | 1 |
+----+-------+
嗯,那我给post加了一个JOIN子句,这样我就可以统计用户的post了,不过我不是很满意与查询,因为额外的 JOIN 子句并且因为结果在每一行中重复 'total' 字段。
SELECT id, userPosts.total as total FROM posts
JOIN (SELECT COUNT(*) AS total FROM posts WHERE uID = 37) AS userPosts
WHERE uID = 37
GROUP BY id, userPosts.total
LIMIT 0,5;
+----+-------+
| id | total |
+------------+
| 1 | 10 |
+----+-------+
| 2 | 10 |
+----+-------+
| 3 | 10 |
+----+-------+
| 4 | 10 |
+----+-------+
| 5 | 10 |
+----+-------+
所以我在想.. 必须有更好的方法来 returning 一个用户的 posts 和 posts 的总数查询,所以 MySQL 结果对象看起来像这样:
(在每个 post 对象中没有 total
)但我找不到任何方法。
{
results: [
{
id: 1
}, {
id: 2
}, {
id: 3
}, {
id: 4
}, {
id: 5
}
],
total: 10
}
也许我应该创建两个单独的 MySQL 查询,一个用于用户的 post,另一个用于总计,然后使用服务器端的辅助函数连接两个响应?
你们有什么建议?我应该创建两个单独的调用来获得上面指定的结果,还是有更好的方法来改进我的查询?
您描述的是 window 计数。在 MySQL 8.0 中,你会做:
select id, count(*) over() as total
from posts
where uid = 37
如果您是 运行 较早的版本,那么 [cross] join
就可以了。您也可以使用相关子查询来表达这一点 - 但逻辑是相同的:
select id, (select count(*) from posts p1 where p1.uid = p.uid) as total
from posts p
where uid = 37
我正在尝试找出在一个查询中 returning posts 和用户的 posts 总数的适当方法。
因此,计算用户 post 总数的最简单方法是:
SELECT COUNT(id) as total FROM posts WHERE uID = 37; +-------+ | total | +-------+ | 10 | +-------+
接下来,我将查询更改为 return post 的 ID,并将总结果限制为前 5 个 post。但是 MySQL 抛出错误 1140...
SELECT id, COUNT(id) as total FROM posts WHERE uID = 37 LIMIT 0,5; Error Code: 1140. In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'db.posts.id'; this is incompatible with sql_mode=only_full_group_by
好的,没有难过的感觉...我不打算更改默认值 'sql_mode' 所以我通过添加
GROUP BY
子句来修复上述错误按照建议进行查询,但现在COUNT()
函数没有多大意义,因为每个结果 returns 1...嗯SELECT id, COUNT(id) as total FROM posts WHERE uID = 37 GROUP BY id LIMIT 0,5; +----+-------+ | id | total | +------------+ | 1 | 1 | +----+-------+ | 2 | 1 | +----+-------+ | 3 | 1 | +----+-------+ | 4 | 1 | +----+-------+ | 5 | 1 | +----+-------+
嗯,那我给post加了一个JOIN子句,这样我就可以统计用户的post了,不过我不是很满意与查询,因为额外的 JOIN 子句并且因为结果在每一行中重复 'total' 字段。
SELECT id, userPosts.total as total FROM posts JOIN (SELECT COUNT(*) AS total FROM posts WHERE uID = 37) AS userPosts WHERE uID = 37 GROUP BY id, userPosts.total LIMIT 0,5; +----+-------+ | id | total | +------------+ | 1 | 10 | +----+-------+ | 2 | 10 | +----+-------+ | 3 | 10 | +----+-------+ | 4 | 10 | +----+-------+ | 5 | 10 | +----+-------+
所以我在想.. 必须有更好的方法来 returning 一个用户的 posts 和 posts 的总数查询,所以 MySQL 结果对象看起来像这样:
(在每个 post 对象中没有 total
)但我找不到任何方法。
{
results: [
{
id: 1
}, {
id: 2
}, {
id: 3
}, {
id: 4
}, {
id: 5
}
],
total: 10
}
也许我应该创建两个单独的 MySQL 查询,一个用于用户的 post,另一个用于总计,然后使用服务器端的辅助函数连接两个响应?
你们有什么建议?我应该创建两个单独的调用来获得上面指定的结果,还是有更好的方法来改进我的查询?
您描述的是 window 计数。在 MySQL 8.0 中,你会做:
select id, count(*) over() as total
from posts
where uid = 37
如果您是 运行 较早的版本,那么 [cross] join
就可以了。您也可以使用相关子查询来表达这一点 - 但逻辑是相同的:
select id, (select count(*) from posts p1 where p1.uid = p.uid) as total
from posts p
where uid = 37