Cause: java.sql.SQLSyntaxErrorException: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'zkms.zkzy_filling_b.filling_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by ; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'zkms.zkzy_filling_b.filling_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
时间: 2025-06-04 21:21:55 浏览: 25
### SQL查询中解决 `only_full_group_by` 导致的 `java.sql.SQLSyntaxErrorException`
在SQL查询中,当启用 `sql_mode=only_full_group_by` 时,如果查询中包含未聚合的列(non-aggregated column),并且这些列没有出现在 `GROUP BY` 子句中,就会触发 `java.sql.SQLSyntaxErrorException`[^1]。这是因为 `ONLY_FULL_GROUP_BY` 模式强制要求所有非聚合列都必须出现在 `GROUP BY` 子句中。
#### 解决方案
1. **调整SQL查询以符合 `ONLY_FULL_GROUP_BY` 的规则**
修改SQL查询,确保所有非聚合列都包含在 `GROUP BY` 子句中。例如,假设有一个查询如下:
```sql
SELECT department_id, employee_name, COUNT(*) AS employee_count
FROM employees
GROUP BY department_id;
```
在此查询中,`employee_name` 是一个非聚合列,且未包含在 `GROUP BY` 子句中,因此会引发错误。可以通过将 `employee_name` 添加到 `GROUP BY` 中来修复:
```sql
SELECT department_id, employee_name, COUNT(*) AS employee_count
FROM employees
GROUP BY department_id, employee_name;
```
2. **使用聚合函数处理非聚合列**
如果某些列不需要出现在结果集中,可以考虑使用聚合函数(如 `MIN()` 或 `MAX()`)来处理这些列。例如:
```sql
SELECT department_id, MAX(employee_name), COUNT(*) AS employee_count
FROM employees
GROUP BY department_id;
```
3. **临时禁用 `ONLY_FULL_GROUP_BY` 模式**
如果无法修改查询逻辑,可以选择临时禁用 `ONLY_FULL_GROUP_BY` 模式。可以通过以下方式设置:
```sql
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
```
注意:这种方法需要管理员权限,并且会影响整个数据库实例的行为[^2]。
4. **通过Java代码动态设置SQL模式**
在Java应用程序中,可以在连接数据库时动态设置SQL模式。例如,使用JDBC连接时,可以在URL中添加参数:
```java
String url = "jdbc:mysql://localhost:3306/mydb?sessionVariables=sql_mode='STRICT_TRANS_TABLES'";
Connection conn = DriverManager.getConnection(url, "username", "password");
```
#### 示例代码
以下是一个完整的示例,展示如何通过Java代码动态调整SQL模式并执行查询:
```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class SqlModeExample {
public static void main(String[] args) throws Exception {
String url = "jdbc:mysql://localhost:3306/testdb?serverTimezone=UTC";
String user = "root";
String password = "password";
// 建立数据库连接
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement()) {
// 设置SQL模式为不包含 ONLY_FULL_GROUP_BY
stmt.execute("SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''))");
// 执行查询
String query = "SELECT department_id, employee_name, COUNT(*) AS employee_count " +
"FROM employees " +
"GROUP BY department_id";
ResultSet rs = stmt.executeQuery(query);
// 处理结果集
while (rs.next()) {
System.out.println(rs.getInt("department_id") + ", " + rs.getString("employee_name") + ", " + rs.getInt("employee_count"));
}
}
}
}
```
#### 注意事项
- 禁用 `ONLY_FULL_GROUP_BY` 模式可能会导致查询结果的不确定性,特别是在非聚合列的值可能因分组而变化的情况下。
- 推荐优先调整查询逻辑以符合 `ONLY_FULL_GROUP_BY` 的规则,而不是简单地禁用该模式。
阅读全文
相关推荐















