在 MySQL 中,当使用 GROUP BY 时,如果想要获取非分组字段的值,MySQL 的处理会有一定限制,因为 SQL 标准要求分组查询中的每个字段要么出现在 GROUP BY 子句中,要么是聚合函数的结果(如 MAX()、MIN()、AVG() 等)。
然而,在 MySQL 中,你可以使用一些方法来获取非分组的字段:
1. 使用 ANY_VALUE() 函数
如果你只需要获取非分组列的任意值(而不关心该值具体是什么),可以使用 ANY_VALUE() 函数。
示例:
SELECT broker_id, ANY_VALUE(broker_name), COUNT(*)
FROM brokers
GROUP BY broker_id;
这里 ANY_VALUE(broker_name) 将返回一个非分组列 broker_name 的任意值。
2. 使用聚合函数
如果你想获取非分组列的具体值,可以通过聚合函数来处理,如 MAX()、MIN()、GROUP_CONCAT() 等。
示例:
SELECT broker_id, MAX(broker_name), COUNT(*)
FROM brokers
GROUP BY broker_id;
在这种情况下,MAX(broker_name) 返回 broker_name 的最大值。
3. 使用子查询或派生表
另一种方式是通过子查询或派生表来获取你想要的非分组列。
示例:
SELECT t1.broker_id, t1.broker_name, t2.total
FROM brokers t1
JOIN (
SELECT broker_id, COUNT(*) AS total
FROM brokers
GROUP BY broker_id
) t2 ON t1.broker_id = t2.broker_id;
通过在子查询中进行 GROUP BY,我们可以在外层查询中获取非分组列的值。
4. 使用 ORDER BY 和 LIMIT 获取特定非分组字段
如果你想获取非分组字段的某个特定值(如最新的记录),可以使用 ORDER BY 和 LIMIT,结合 GROUP BY 来获取特定的行。
示例:
SELECT broker_id, broker_name
FROM brokers
WHERE (broker_id, created_at) IN (
SELECT broker_id, MAX(created_at)
FROM brokers
GROUP BY broker_id
);
这个查询会返回每个 broker_id 对应的最新 created_at 的 broker_name。
5. 在 MySQL 5.7+ 中 ONLY_FULL_GROUP_BY
在 MySQL 5.7+,ONLY_FULL_GROUP_BY 模式默认开启,这意味着必须严格按照 SQL 标准处理分组查询。如果你的查询试图获取非分组列而未使用聚合函数,MySQL 会抛出错误。你可以通过 ANY_VALUE() 或者上述的聚合函数来规避这个问题,或者通过关闭该模式来允许更宽松的语法(不推荐在生产环境中关闭此模式)。
关闭 ONLY_FULL_GROUP_BY 的方法:
SET sql_mode = (SELECT REPLACE(@@sql_mode, ‘ONLY_FULL_GROUP_BY’, ”));
总结:
- ANY_VALUE():获取非分组列的任意值。
- 聚合函数:如 MAX()、MIN() 来获取非分组列的具体值。
- 子查询:通过子查询来规避分组限制。
- ORDER BY 和 LIMIT:可以获取某一行中的非分组列。
根据你的具体需求选择合适的方案来处理非分组参数。