Mysql的distinct、order by和group by冲突报错

本文介绍在不同MySQL版本中实现前端下拉框数据按时间倒序排序并去重的方法。通过对比distinct+orderby、groupby+orderby等策略,推荐使用先排序后去重的方式,解决了因数据库版本差异导致的语法错误。

项目场景:

需求:前端下拉框(字段A)数据需要根据时间字段(字段B)倒序排序且去重返回(结果集是List<String>)

思路:1、distinct+order by;2、group by+order by;3、order by+java的set集合;4、先order by排序后distinct去重;


问题描述和分析

踩坑经历:由于我本地数据库的版本是5.7.35-log,项目发布线上数据库版本是5.7.39,思路1和思路2在5.7.35-log版本都可运行,但是发布到5.7.39上就会报错(思路1报错:...which is not in SELECT list; this is incompatible with DISTINCT,思路2报错:...which is not functionally dependent on columns in GROUP BY clause;)。

分析原因是:5.7.39版本的Mysql语法更加严格了,Distinct关键字也带排序且优先级大于order by,且order by和group by后的字段在select中必须存在。

Mapper.java中显示:

@Repository
public interface ProcessExaminerMapper {
    List<String> getAllBatchByJudge();
}

Mapper.xml中显示: 

#思路1、distinct+order by
<select id="getAllBatchByJudge" resultType="java.lang.String">
    SELECT DISTINCT
	    batch 
    FROM
	    st_process_examiner 
    ORDER BY
	    create_time DESC
</select>


#思路2、group by+order by
<select id="getAllBatchByJudge" resultType="java.lang.String">
    SELECT
	    batch 
    FROM
	    st_process_examiner 
    GROUP BY
	    batch 
    ORDER BY
	    create_time DESC
</select>


解决方案:

 解决方法:推荐思路4:先order by排序后distinct去重(一句sql解决,且速率快),
思路3可以用但不推荐,这里就不写了,详细思路:就是双层for循环,外层循环是order by的有顺序的list,内层循环是set集合,循环体操作:if判断匹配元素,匹配到则插入一个新的list(返回的结果集合)并且set.remove("匹配的元素"),这样做是为了减少内部循环次数

 Mapper.xml中显示:

#思路4、先order by排序后distinct去重

<select id="getAllBatchByJudge" resultType="java.lang.String">
    SELECT DISTINCT
	    batch 
    FROM
	    ( SELECT DISTINCT batch, create_time FROM st_process_examiner
	    ORDER BY create_time DESC ) a
</select>

结束语:我们一生中可能只能决定5%的事情,决定不了出生、智商和贵人相助,但是没有谁的剧本值得羡慕,只能把自己的剧本演好。

### MySQL中 `ORDER BY`、`GROUP BY` `DISTINCT` 的用法及区别 #### 1. 基本定义与用途 - **`ORDER BY`**: 用于对查询结果按照一个或多个字段进行排序。默认情况下,它是升序排列 (`ASC`),可以通过指定 `DESC` 来实现降序排列[^4]。 - **`GROUP BY`**: 主要用于将具有相同值的行分组在一起,并通常配合聚合函数(如 `SUM()`、`COUNT()`、`AVG()` 等)一起使用,以便对每组数据进行统计分析[^2]。 - **`DISTINCT`**: 用于消除查询结果中的重复行,仅保留唯一的结果集。它一般应用于简单查询场景下,不需要复杂的计算或分组操作[^3]。 #### 2. 使用方法 ##### (1) `ORDER BY` ```sql SELECT column_name(s) FROM table_name WHERE condition ORDER BY column_name_1 ASC|DESC, column_name_2 ASC|DESC; ``` 示例: ```sql SELECT name, age FROM users ORDER BY age DESC; -- 按照年龄降序排列 ``` ##### (2) `GROUP BY` ```sql SELECT grouping_columns, aggregate_functions FROM table_name WHERE conditions GROUP BY grouping_columns; ``` 示例: ```sql SELECT department_id, COUNT(*) AS employee_count FROM employees GROUP BY department_id; -- 统计每个部门的员工数量 ``` ##### (3) `DISTINCT` ```sql SELECT DISTINCT column_name(s) FROM table_name WHERE conditions; ``` 示例: ```sql SELECT DISTINCT city FROM customers; -- 获取客户所在城市的唯一列表 ``` #### 3. 性能比较 - **`DISTINCT` vs `GROUP BY`**: - 当只需要去重而无须额外的聚合运算时,`DISTINCT` 的性能可能优于 `GROUP BY`,因为后者可能会涉及隐式的排序操作[^1]。 - 不过,在某些特定条件下(例如能够有效利用索引),两者之间的性能差距并不明显[^5]。 - **`ORDER BY` 影响**: - 添加 `ORDER BY` 后可能导致文件排序(`FileSort`)的发生,从而降低整体查询速度。因此应谨慎评估是否真的需要此选项以及能否借助现有索引来优化该过程。 #### 4. 应用场景对比 | 特性/命令 | ORDER BY | GROUP BY | DISTINCT | |------------------|-----------------------------------|---------------------------------------|------------------------| | 功能 | 排序 | 数据分组并可选配聚合 | 返回不重复的数据项 | | 是否改变原始数据结构? | No | Yes | Yes | | 配合使用的常见组件 | 单独使用 | 聚合函数(如 SUM(), AVG()) | None | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热心码民阿振

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值