虽然是一个常见的 SQL 报错缺陷,但是仍要记录一下解决的过程。

因为开始实习后好长时间不写学习记录了,这篇算是之后的学习记录再出发的一个起点!

错误出现

接口 500,本地 debug 轻松地发现了问题:是 Mapper 中的一条 SQL 有问题,Column 'short_name' in order clause is ambiguous

SQL并不复杂,数据库结构就不赘述了,四张表连接查询。直接看问题 SQL:

SELECTp.*,lt.NAME AS province_name,t.NAME country_name FROMsm_basic_province pLEFT JOIN sm_basic_country bc ON p.country = bc.country_idLEFT JOIN sm_basic_lang_tag t ON bc.NAME = t.tag_id AND t.lang = 1 AND t.tenant_id = 'keycai'LEFT JOIN sm_basic_lang_tag lt ON p.NAME = lt.tag_id AND lt.lang = 1 AND lt.tenant_id = 'keycai' WHEREp.tenant_id = 'keycai' AND bc.tenant_id = 'keycai'
ORDER BY CONVERT ( short_name USING gbk ) DESC

问题很明显、很常见,short_name 字段名不明确。

错误解决

常规方法 ORDER BY 之前的查询结果加括号:

(SELECTp.*,lt.NAME AS province_name,t.NAME country_name FROMsm_basic_province pLEFT JOIN sm_basic_country bc ON p.country = bc.country_idLEFT JOIN sm_basic_lang_tag t ON bc.NAME = t.tag_id AND t.lang = 1 AND t.tenant_id = 'keycai'LEFT JOIN sm_basic_lang_tag lt ON p.NAME = lt.tag_id AND lt.lang = 1 AND lt.tenant_id = 'keycai' WHEREp.tenant_id = 'keycai' AND bc.tenant_id = 'keycai')
ORDER BY CONVERT ( short_name USING gbk ) DESC

错误依旧,SELECT * (…) t 生成中间表 t,再根据 t 表的 short_name 字段进行排序:

SELECT * FROM (SELECTp.*,lt.NAME AS province_name,t.NAME country_name FROMsm_basic_province pLEFT JOIN sm_basic_country bc ON p.country = bc.country_idLEFT JOIN sm_basic_lang_tag t ON bc.NAME = t.tag_id AND t.lang = 1 AND t.tenant_id = 'keycai'LEFT JOIN sm_basic_lang_tag lt ON p.NAME = lt.tag_id AND lt.lang = 1 AND lt.tenant_id = 'keycai' WHEREp.tenant_id = 'keycai' AND bc.tenant_id = 'keycai') t
ORDER BY CONVERT ( short_name USING gbk ) DESC

至此,问题解决。

错误分析

可以去回看一下最开始出问题的 SQL,根据 SELECT 后面的字段,不该出现 short_name 不明确的问题。

虽然在 sm_basic_provincesm_basic_country 两张表中都存在 short_name 字段,但是只查询了 sm_basic_province 中的 short_name 字段。

删掉 CONVERT() 函数,尝试执行:

SELECTp.*,lt.NAME AS province_name,t.NAME country_name FROMsm_basic_province pLEFT JOIN sm_basic_country bc ON p.country = bc.country_idLEFT JOIN sm_basic_lang_tag t ON bc.NAME = t.tag_id AND t.lang = 1 AND t.tenant_id = 'keycai'LEFT JOIN sm_basic_lang_tag lt ON p.NAME = lt.tag_id AND lt.lang = 1 AND lt.tenant_id = 'keycai' WHEREp.tenant_id = 'keycai' AND bc.tenant_id = 'keycai'
ORDER BY short_name DESC

正确执行。

正常来讲一条 SQL 的执行顺序是:

FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY -> LIMIT
每步执行都会产生一个虚表,作为当前执行步骤的输出和下一步执行时的输入,只有当最后一步执行完后这个虚表才会作为这条被执行 SQL 的最终结果。

按照这个执行顺序,CONVERT() 执行的时候应该已经没有重复的列了,说明这个函数是在 SELECT 之前就执行了,因为这时候的虚表中存在相同名称的列,所以报了 ambiguous 错误

至此解决了问题,但是原理层面仅停留在猜测,并没有找到权威的材料证明,也没有想到什么好的验证方法。

如果有知道原因的大神,还望赐教!

本篇未完待续。。。。


菜鸟本菜,不吝赐教,感激不尽!

更多题解源码和学习笔记:github 、CSDN 、M1ng

MySQL报错Column xxxx in xxxx clause is ambiguous相关推荐

  1. docker compose 安装mysql报错 column count of performance_schema.events....

    报错内容如下: 原因:多次安装未清理数据卷,清理完重新安装 清理数据卷用以下命令 docker volume ls #查询 docker volume rm [卷名] 如果你手动去相应目录删除会报如下 ...

  2. mysql 报错解决思考Expression #5 of SELECT list is not in GROUP BY clause and contains nonaggregated column

    mysql报错: [Err] 1055 - Expression #5 of SELECT list is not in GROUP BY clause and contains nonaggrega ...

  3. MySQL报错 SELECT list is not in GROUP BY clause and contains nonaggregated column...

    MySQL报错 SELECT list is not in GROUP BY clause and contains nonaggregated column- 原因: 在mysql5.7以上的版本中 ...

  4. mysql报错Table ‘xxxx‘ doesn‘t exist

    mysql报错Table 'xxxx' doesn't exist 问题 pear_admin 开源项目的定时任务使用的是 quartz quartz 默认的表初始化脚本都是表明 大写 作者为了表名符 ...

  5. MySQL报错1055解决办法:[Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains

    [mysql报错1055 报错解决办法][Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and cont ...

  6. mysql报错:1406, Data too long for column

    mysql报错:1406, "Data too long for column pymysql.err.DataError: (1406, "Data too long for c ...

  7. MySQL报错:Data truncated for column 的原因之一

    关于MySQL报错:执行数据更新时报错提醒:Data truncated for column '字段名' at row 1. 原因有1:先前已经定义了"列表名",并且已经 *赋值 ...

  8. mysql报错:Reading table information for completion of table and column names

    一.前言 在使用命令行打开数据库的时候,报错如标题所示.这里总结记录一下. 二.错误原因 1.锁表的原因 参考链接:https://blog.csdn.net/ssergsw/article/deta ...

  9. 【问题】连接mysql报错errorCode 0, state 08S01

    [问题]连接mysql报错errorCode 0, state 08S01 解决方案 只需要加上&useSSL=false url: jdbc:mysql://localhost:3306/x ...

  10. 由mysql报错注入引发的探究与思考(Group by, rand函数相关,松散索引扫描、紧凑索引扫描相关)

    目录 本文要点 原理探讨(Group by, rand函数相关) 进一步的思考:索引与Group By语句 本文要点 当服务器没有关闭报错回显信息显示时,便可考虑实施报错注入类型的Mysql注入攻击. ...

最新文章

  1. jstree中文api文档_开发中文 API 的一些策略
  2. c++强大还是python强大-2020,你该学习Python还是C++
  3. pthread属性使用(转)
  4. 图解MongoDB的连接与使用,通俗易懂
  5. Java集合从菜鸟到大神演变
  6. 修改npm默认全局安装路径
  7. R语言学习笔记(一)R语言的基本操作与函数
  8. java 常量池溢出_Java方法区和运行时常量池溢出问题分析(转)
  9. Linux下Git免输密码解决方式
  10. 向上取整和向下取整(ceil、round)
  11. 图片相似度识别在线_玩转腾讯词向量:词语相似度计算和在线查询
  12. 法律人学python_你要埋头苦学三个月,然后悄悄惊艳所有人。python速成大法满足你所有的要求!...
  13. cmd换行 windows_键盘键位修改及管理(Windows篇)
  14. ORA-01017解决方案
  15. 《计算机网络教程》(微课版 第五版) 第六章 网络应用层 课后习题及答案
  16. 世界银行的WDI世界发展指标数据EXCEL版本(1960-2017年)
  17. 半圆形进度条(vue加强版)
  18. 1个钟是多久_一个时辰是多久,一个时辰是几个小时?
  19. Fiddler 和 Wireshark抓包教程合集
  20. C语言:解一元二次方程

热门文章

  1. 怎么启动计算机后台打印服务,Win10系统中打印机后台服务没有启动解决方法
  2. 怎么将欧姆龙PLC数据转OPC UA
  3. **使用InkScape绘制简易字母LOGO的教程**
  4. java根据出生日期计算年龄_通过出生日期获取年龄的方法--Java
  5. Win系统 - 微星 GS65 笔记本电脑开机黑屏
  6. html5图片如何变成圆圈,h5中使用canvas把图片缩放并且剪切成圆形
  7. iOS-苹果官方开源网站;objc、Runloop、GCD、OC等开源代码
  8. SCAU 菱形打印全集
  9. html老师祝福语,给大学老师的祝福语
  10. css 实现一个尖角_请用CSS实现一个带尖角的正方形