关于mysql版本差异导致FIND_IN_SET()查询不到数据的问题

这次发现的问题,是在接手项目的时候,和安卓端小伙伴测试时候发现的,插入数据之后却查不出来,通过排查定位到FIND_IN_SET()函数,也是第一次接触FIND_IN_SET(),特此记录一下~

关于FIND_IN_SET():

官方涵义(MySQL手册中语法说明)

FIND_IN_SET(str,strlist) : str 要查询的字符串,strlist 需查询的字段,参数以”,”分隔,形式如 (1,2,6,8,10,22);该函数的作用是查询字段(strlist)中是否包含(str)的结果,返回结果为null或记录。

假如字符串str在由N个子链组成的字符串列表strlist 中,则返回值的范围在 1 到 N 之间。 一个字符串列表就是一个由一些被 ‘,’ 符号分开的子链组成的字符串。如果第一个参数是一个常数字符串,而第二个是type SET列,则FIND_IN_SET() 函数被优化,使用比特计算。 如果str不在strlist 或strlist 为空字符串,则返回值为 0 。如任意一个参数为NULL,则返回值为 NULL。这个函数在第一个参数包含一个逗号( , )时将无法正常运行。数为NULL,则返回值为 NULL。这个函数在第一个参数包含一个逗号( , )时将无法正常运行。

示例:

SELECT FIND_IN_SET('b', 'a,b,c,d');

// 结果:2

// 因为 b 在strlist集合中2的位置, a是位置1

select FIND_IN_SET('1', '1');

// 结果:1

// 这时候的strlist集合有点特殊,只有一个字符串

select FIND_IN_SET('2', '1,2');

// 结果:2

select FIND_IN_SET('6', '1');

// 结果:0 strlist中不存在str,所以返回0。

综上: FIND_IN_SET函数中,若前一个字符串包含在后一个字符串集合中,返回大于0的数,该数为前一个字符串在后一个字符串中的位置。

问题发生:

有一张发布作业表,表中有个varcher类型字段用于存储班级id,存入的形式是 ‘01,02,03’,而现在要用另外一张表,通过学生所在的班级id,从发布作业表中获取相关老师布置的作业,,接手项目时,sql语句如下:

SELECT

m.class_id,

m.prod_key,

m.dev_name,

w.id work_id,

w.title,

w.content,

w.is_open,

w.score,

w.file_url_list,

w.end_time,

w.create_author,

w.update_author

FROM

sc_work w,

sc_class_mem m

WHERE

w.id = 56

AND find_in_set(m.class_id, w.class_ids)

AND m.identity=0;

问题解决:

在安卓小伙伴进行测试的时候所拿到的相关字段数据是空的,通过debug发现执行这个sql语句后,获取到的值是null。但是本地数据与测试服务器的数据库数据是一致的,所以应该可以查询到值才对,所以我认为是前者写的sql语句有问题(因为此前就有出现过好几次这个问题,再加上我在本地执行sql语句查询不到任何数据),但我还是将映射文件中的sql语句放到测试服务器的数据库执行发现是可以查询到的,首先想到的是不是本地mysql版本(8.0.26)不支持这个函数,但是实际发现是支持的,然后又去看了一下库中表的字符集,发现是utf32,而我创建的时候是utf8mb4,然后便重新创建库,字符集选了utf32,测试是不是这个原因,但是实际结果发现并不是这个原因,于是便去查询相关资料,以及修改sql语句,我发现:

find_in_set(m.class_id, '45,46,46')

如果将两个字段任一换成’xx,xx,xx’,就可以查询的到,就很奇怪。

而网上资料全是讲解如何使用,千篇一律,没有起到帮助,想了很久,虽然一开始有想到了是不是数据库版本的问题,但是没有马上去测试这个想法,因为我觉得8.0.19和本地8.0.26应该差别不大才对啊,而且官方文档这个函数还存在,版本越高不是越能向下兼容? 查了一天,想了很久不知道问题出在哪里,最后还是在虚拟机拉取了一个mysql8.0.19的镜像下来,进行测试,最终发现是数据库版本的问题,至此问题得到解决,又长见识了~

漂亮!又浪费了一天时间~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
find_in_set在PostgreSQL中不起作用的原因是因为它是MySQL特有的函数,无法在PostgreSQL中使用。在PostgreSQL中,你可以使用其他方法来实现相同的功能。一个常见的方法是使用string_to_array函数将包含多个值的字段转换为数组,然后使用ANY或IN操作符来查询包含某个特定值的数据。例如,你可以使用以下语句来查询包含值为1的数据: SELECT * FROM your_table WHERE '1' = ANY (string_to_array(your_column, ',')); 这将把your_column字段中以逗号分隔的值转换为一个数组,并检查数组中是否包含值为1的元素。如果包含,则返回相应的数据行。请注意,你需要将your_table替换为你的表名,your_column替换为你的字段名。 希望这可以帮助到你解决问题。如果还有其他问题,请随时提问。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Mysql 使用FIND_IN_SET函数 case when 失效](https://blog.csdn.net/weixin_45684858/article/details/126459955)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [PostgresSQL查询数据中用逗号隔开的数据以及@>与的区别](https://blog.csdn.net/qq_19734597/article/details/127210564)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值