当使用 MySQL 的 GROUP BY 语句时,根据指定的列对结果进行分组。在 GROUP BY 分组时,如果某个字段在分组中有多个不同的值,那么就会出现你提到的该字段一直在变化的情况。

这种情况通常是由于在 GROUP BY 中选择的字段与其他非聚合字段不兼容,或者在 SELECT 子句中没有正确使用聚合函数所导致的。

以下是一些常见的情况和解决方法:

选择的字段不兼容:在 GROUP BY 子句中指定的字段必须与 SELECT 子句中的字段兼容。如果在 GROUP BY 子句中选择了某个字段,而在 SELECT 子句中选择了该字段以外的其他字段,那么结果集可能会出现问题,导致字段值不稳定。确保 GROUP BY 子句中的字段与 SELECT 子句中的字段一致。

忘记使用聚合函数:如果在 SELECT 子句中选择了非聚合字段,而在 GROUP BY 子句中指定了其他字段,那么 MySQL 将会随机选择一条记录的值作为结果。这可能导致字段值在结果集中变化。在这种情况下,你需要使用适当的聚合函数(如 SUM、MAX、MIN、COUNT 等)来计算非聚合字段的值。

案例1

在项目中,需要统计用户的领取金额,一个申请单可以有多个用户(好比我可以帮我父母领取),当管理员创建了申领订单后这些用户就可以去领取了。

mysql group by显示次数 mysql中的group by_数据库


由于页面上需要查看明细,所以查询的时候根据产品的需求就使用apply_code和pax_id进行group by。这个时候就会出现问题,pax_id相同的那条数据的order_id字段就会变得随机

mysql group by显示次数 mysql中的group by_数据库_02


mysql group by显示次数 mysql中的group by_数据库_03


两次的order_id不一样,这样就会给管理者核对的时候带来困惑。

由于我们的业务特殊性,所以我们的方案是把order_id用逗号拼接起来展示。

如果你希望将某个字段的值使用逗号连接在一起,可以使用 MySQL 的 GROUP_CONCAT 函数。GROUP_CONCAT 函数可以将指定字段的值按照指定的分隔符连接成一个字符串。

以下是使用 GROUP_CONCAT 函数的示例:

SELECT group_concat(your_field SEPARATOR ',') AS concatenated_values
FROM your_table
GROUP BY some_other_field;

在上面的示例中,your_field 是要连接的字段名,your_table 是表名,some_other_field 是用于分组的其他字段名。SEPARATOR ‘,’ 指定了连接字符串时使用的分隔符,这里是逗号。

执行上述查询后,会得到一个名为 concatenated_values 的结果列,其中包含了字段值按照逗号连接在一起的字符串。

请注意,GROUP_CONCAT 函数有一个默认的最大连接长度限制(默认为 1024 字符)。如果你的连接结果超过了该限制,可以通过设置 group_concat_max_len 参数来增加最大连接长度,例如

SET SESSION group_concat_max_len = 10000;

这将将最大连接长度增加到 10000 字符。你可以根据需要调整该值。

案例2

未使用聚合函数的非聚合字段:

SELECT name, age
FROM students
GROUP BY age;

在上述查询中,我们希望按照年龄分组学生信息。然而,由于在 SELECT 子句中选择了非聚合字段 name,而没有使用聚合函数,MySQL 将会随机选择一条记录的姓名作为结果。这将导致结果集中的姓名字段值出现变化。

解决方法是使用适当的聚合函数

SELECT MAX(name), age
FROM students
GROUP BY age;

在这个查询中,我们使用了 MAX() 聚合函数来计算每个年龄组的最大姓名,并确保在 GROUP BY 分组时,姓名字段的值是稳定的。

案例3

GROUP BY 子句与 SELECT 子句字段不兼容:

SELECT name, age
FROM students
GROUP BY name;

在上述查询中,我们希望按照姓名分组学生信息。然而,由于在 GROUP BY 子句中选择了 name 字段,而在 SELECT 子句中同时选择了 name 和 age 字段,结果集会包含多个不同的年龄值,导致字段值出现变化。

解决方法是确保 GROUP BY 子句和 SELECT 子句中的字段一致:

SELECT name, MAX(age) AS age
FROM students
GROUP BY name;

在这个查询中,我们使用 MAX() 聚合函数计算每个姓名组的最大年龄,并确保在 GROUP BY 分组时,年龄字段的值是稳定的。

总结

请确保在 GROUP BY 查询中正确使用聚合函数,并且 GROUP BY 子句中的字段与 SELECT 子句中的字段一致。这样可以确保结果集按照预期进行分组,并避免某个字段一直变化的问题。