【发布时间】:2018-09-11 14:33:16
【问题描述】:
我正在执行一个SELECT 查询,其中有一个MAX() 列和一个GROUP BY 子句,除了我需要返回给客户端的查询结果之外,我还需要同时返回所有结果的总数。
基本上我的查询是这样的:
SELECT unique_id, col1, col2, MAX(col3) as col3
FROM tbl
GROUP BY col1, col2
它通常也会有一个WHERE 子句。
unique_id 是表的主键。
当将此数据返回给客户端时,我还指定了LIMIT 和OFFSET 子句来限制一次检索的结果数量。我的问题是,如果上面的查询没有 LIMIT 和 OFFSET 子句,我还需要显示结果的总数,以便客户端可以稍后/增量检索其余部分。
我知道我可以轻松地使用 WITH 临时表来获得我想要的:
WITH temp AS (
SELECT unique_id, col1, col2, MAX(col3) as col3
FROM tbl
GROUP BY col1, col2
)
SELECT count(*) FROM temp
但我担心这样做的效率。 sans-LIMIT-and-OFFSET 查询可以返回数万行,所以我认为获取总数的WITH 方法并不是最好的方法。
有没有更有效的方法,我没有想到?还是WITH 方法很好(例如,MySQL 服务器“智能”到足以不分配查询的整个结果集来获取计数)?
示例数据
假设这是我表中的数据:
unique_id col1 col2 col3
___________________________
1 5 8 30
2 5 8 33
3 5 9 40
4 6 8 30
5 6 8 31
6 6 8 32
7 6 9 39
8 7 8 33
9 7 8 32
10 8 8 34
所以我的SELECT 查询会返回这个(假设客户端指定LIMIT 4 OFFSET 0):
SELECT unique_id, col1, col2, max(col3) as col3
FROM tbl
GROUP BY col1, col2
LIMIT 4
OFFSET 0;
unique_id col1 col2 col3
___________________________
2 5 8 33
3 5 9 40
6 6 8 32
7 6 9 39
然后我会使用该查询没有 LIMIT 和 OFFSET 子句作为子查询和 SELECT COUNT(*) 从它,这将返回 6,我会返回6 和客户端的结果。
【问题讨论】:
-
你用的是什么版本的 MySQL?
-
@GordonLinoff MySQL 8
-
您没有按
unique_id分组,但您正在返回它。 MySQL 确实有一种模式允许您选择非 GROUP BY 列作为非聚合列,但这并不意味着将它用于您在这里所做的事情是一个好主意。您无法可靠地预测在这种情况下将返回哪个unique_id,那么为什么首先返回它呢? -
看起来您需要每个
col1和col2的最大col3并且还需要具有这 3 个值的uniqe_id。你确认了吗? -
@AndriyM 我明白你的意思。我们将
unique_id返回到 GUI 的唯一原因是我们可以也许稍后引用它,并且由于我们正在分组,返回的组的特定unique_id,虽然确实不可预知,真的没那么重要。只要我们可以引用其中一个,我们就可以引用整个组。