【问题描述】
以下在 MySQL 中可正常执行的 SQL,在迁移至 YashanDB 后却出现执行错误:
SELECT Sname, Ssex, MIN(Sage) FROM Student GROUP BY Ssex;
SELECT Sname, COUNT(0) AS counts FROM Student;
SELECT
MIN(st.Sage),
SC.CId,
MIN(st.SId),
MIN(SC.score)
FROM Student st
LEFT JOIN SC ON st.SId = SC.SId
GROUP BY SC.CId
ORDER BY st.Sage;
复制代码
崖山数据库执行时报错:
YAS-04316 not a single-group group function
复制代码
【问题根因】
该问题与 SQL 标准差异 有关。
MySQL(默认宽松模式):
允许在 GROUP BY 中出现未聚合也未出现在分组条件中的列。系统会“任取一行”作为该列值返回。
YashanDB / Oracle / PostgreSQL:
严格遵循 SQL-92 标准。要求:
所有非聚合字段,必须出现在 GROUP BY 中。
因此,在崖山上执行以上 SQL 会报错。
【对比说明】
说明:MySQL 从 5.7 开始,默认也启用了 ONLY_FULL_GROUP_BY 模式,逐步与 SQL-92 接轨。
【解决方法】
✅ 方法一:使用聚合函数替代非分组字段
-- 原写法(MySQL 风格)
SELECT Sname, Ssex, MIN(Sage) FROM Student GROUP BY Ssex;
-- 修改后(SQL-92 合规)
SELECT MIN(Sname), Ssex, MIN(Sage) FROM Student GROUP BY Ssex;
复制代码
可以根据业务语义选择 MIN(Sname) 或 MAX(Sname)。
✅ 方法二:拆分成子查询解决 GROUP BY + ORDER BY 冲突
-- 原写法(崖山不支持)
SELECT MIN(st.Sage), SC.CId, MIN(st.SId), MIN(SC.score)
FROM Student st
LEFT JOIN SC ON st.SId = SC.SId
GROUP BY SC.CId
ORDER BY st.Sage;
-- 推荐写法
SELECT * FROM (
SELECT SC.CId,
MIN(st.Sage) AS mage,
MIN(st.SId),
MIN(SC.score)
FROM Student st
LEFT JOIN SC ON st.SId = SC.SId
GROUP BY SC.CId
) tmp
ORDER BY mage;
复制代码
【总结建议】
YashanDB 遵循严格 SQL-92 标准;
MySQL 早期语法宽松,迁移需注意;
所有非聚合字段应出现在 GROUP BY 中,或使用聚合函数处理;
推荐:开启 MySQL 的 ONLY_FULL_GROUP_BY 进行 SQL 规范检查,提前规避迁移风险。
评论