背景

今天同事让帮忙写个sql,大致是一张表的两个字段都关联另外一张表的主键,这个完全可以把两个表当作三个表来写,大概是这种:

SELECT
t1.name,
t1.id,
t2.reason,
t3.result
FROM
test1_copy1 AS t1
INNER JOIN test1 AS t2 ON t1.id = t2.reason
INNER JOIN test1 AS t3 ON t1.id = t3.result

这种是可以实现的,但是我看到数据里的另一个点,那就是t2.reason字段,存放的是用逗号隔开的字符串,如下所示,kg_rules表的reason和result对应kg_facts表的id,查询kg_rules表的每一条记录对应的名字(name)和含义(mean)

第一步:先使用find_in_set解决范围查找

SELECT
a.id,
b.name
FROM
kg_rules a
LEFT JOIN kg_facts b ON FIND_IN_SET(b.id, a.reason)

结果为:

这里会看到根据表kg_rules的reason,找到了三条记录。达到了我想要的结果,来分享记录一下Mysql这个方法吧。

1.认识find_in_set()函数

Mysql官方文档手册,如下图:

2.find_in_set()基本操作

select find_in_set (‘b’, ‘a,b,c,d,w’);
结果为2,因为b字符串在strlist集合中,在第二个位置,起始数是从1开始的

select find_in_set(‘6’,‘1,2’);
结果为0,因为第一个字符串6,并不在第二个参数中

对于上面写的sql语句,使用find_in_set()进行数据查询的时候,一次可以返回多条记录的情况

上面的语句类似于in()如下的操作:

select id,name from kg_facts where id in(1,2,3)

3.find_in_set()与in()的应用场景区别

刚刚上面的情况也看到了

select * from kg_facts where find_in_set(id,‘1,2,3’)

select * from kg_facts where id in(1,2,3)

两个结果是一样的。不一样就在于一个有单引号,一个没有。这里也要针对你药检测的字段是数字类型还说字符串类型。

对于find_in_set()而言,第二个参数无论是字符串还说数字,都必须用单引号括起来,并且列表中用逗号隔开,这个字符串列表是一个整体。

对于in()而言,如果检测的字段是数字类型就不能用单引号,因为会出现偏差。
例:

select * from kg_facts where id in(1,2,3) —正确的
select * from kg_facts where id in(‘1,2,3’) —错误的


你看只有一个结果,这是因为Mysql会自动判断字符串的第一个是否匹配,但是后面的就被截掉了,不进行匹配!!

如果检测的是字符串,那么使用in()的时候,每个字符串都应该被单引号括起来

select * from per where paddr in(‘重庆’,‘北京’,‘上海’);
比较
select * from per where find_in_set(paddr,‘重庆,北京,上海’);

小结

查字段固定的内容时,比如: 字段名 in (‘篮球’,‘足球’,‘羽毛球’),
查是否有包含in中独立存在的信息时,用in
查字段的内容是否包含其中一个指定的关键词内容时,用find_in_set

SELECT id,name,list from test1 WHERE list in(‘篮球’,‘足球’); #-- 返回list字段内容只是篮球 或 足球的数据
SELECT id,name,list from test1 WHERE find_in_set(‘篮球’,list); #-- 返回list字段内容中包含了篮球的数据

4.find_in_set() 与like()的应用场景区别

在数据库查询的时候,需要得到某字段中包含某个值的记录,但是它并不是like能解决的,因为使用like可能会查到我们不想要的就,这个时候find_in_set函数就可以用了
需求:查询用户拥有权限编号为2的

select * from users_test where limits like ‘%2%’;


结果看到了,并不是我们想要的,那么使用find_in_set函数来看看

select * from users_test where find_in_set(2,limits)

小结

1.find_in_set(str, strlist)字符串函数是返回strlist中str所在的位置索引,strlist必须以英文逗号隔开
2.like是广泛的模糊查询,字符串中没有分隔符
3.find_in_set是精确匹配,查询结果比like查询更精确!

第二步:多表关联

了解完find_in_set函数后,我们来直接多表查询,

SELECT
b.id,
a.id,
b.name,
c.name
FROM
kg_rules a
LEFT JOIN kg_facts b ON FIND_IN_SET(b.id, a.reason)
left join kg_facts c on a.result=c.id;

因为用了find_in_set函数,所以有多条查询结果

看这个结果,也不是我想要,我想要同一个id,对应一条记录,并把多条记录放在一个字段展示

第三步:group_concat()函数合并列 — 组内拼接函数

下面的操作就是常见的需求,右边显示一列组名,右边显示组名下所有的成员信息;这里也是可以使用的
** group_concat 必须与group by函数一起使用**

1.group_concat的语法

group_concat([distinct] 要连接的字段 [order by AEC/DESC 排序字段] [separator ‘分隔符’] )

2.使用例子

多种使用的例子,不清楚可以查看

那么最终的需求转化为sql为:

SELECT
a.id,
b.id as beifen,
GROUP_CONCAT(b.name),
c.name
FROM
kg_rules a
LEFT JOIN kg_facts b ON FIND_IN_SET(b.id, a.reason)
left join kg_facts c on a.result=c.id
GROUP BY a.id;

含义为:以表a(kg_rules )的id为基准,将查询的多条记录,对表b(kg_facts)的name进行拼接,采用默认逗号的方式拼接,当然可以使用separator 来自定义拼接符号。

注意:

  • 1.int字段的拼接陷阱
    使用group_concat的时候,若是连接起来的字段如果是int型,一定要转为char再拼接。否则在你智行后返回的将不是一个逗号隔开的串,而是byte[]

    select group_concat(id) from t_ip — 返回byte[]
    select group_concat(Convert(id , char)) from t_dep ----返回逗号隔开的串

  • 2.长度陷阱
    用了group_concat后,select里如果使用了limit是不起作用的
    用group_concat连接字段的时候是有长度限制的,不过可以设置

使用group_concat_max_len系统变量,可以设置允许的最大程度,程序中语法如下,其中val是一个无符号的整数

set [SESSION | GLOBAL] group_concat_max_len = val;

默认是1024。

写在最后

其实,我也是边百度边学习,发现百度是万能的,如果使用group_concat的时候,提示:

1055 - Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘myself.b.id’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

这个是mysql配置问题,网上也有很多的解决办法

Mysql中find_in_set()函数与in()函数的用法相关推荐

  1. mysql中find_in_set()函数的使用及in()用法详解

    From: http://www.manongjc.com/article/2710.html MySQL手册中find_in_set函数的语法解释: FIND_IN_SET(str,strlist) ...

  2. mysql中find_in_set()函数的使用和排序,且与in(),like()的比较详解

    MySQL手册中find_in_set函数的语法解释: FIND_IN_SET(str,strlist) str 要查询的字符串 strlist 字段名 参数以","分隔 如 (1 ...

  3. mysql中locat函数,MySQL中的LOCATE和POSITION函数使用方法 | 很文博客

    不常用:MySQL中的LOCATE和POSITION函数 LOCATE(substr,str) POSITION(substr IN str) 返回子串 substr 在字符串 str 中第一次出现的 ...

  4. mysql的json函数与实例_Mysql实例详解Mysql中的JSON系列操作函数

    <Mysql实例详解Mysql中的JSON系列操作函数>要点: 本文介绍了Mysql实例详解Mysql中的JSON系列操作函数,希望对您有用.如果有疑问,可以联系我们. MYSQL必读前言 ...

  5. mysql 排名_学会在MySQL中实现Rank高级排名函数,所有取前几名问题全部解决.

    MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名 ...

  6. mysql中locat函数,MySQL中的LOCATE和POSITION函数使用方法

    不常用:MySQL中的LOCATE和POSITION函数 LOCATE(substr,str) POSITION(substr IN str) 返回子串 substr 在字符串 str 中第一次出现的 ...

  7. Mysql中当前日期(时间)函数总结

    Mysql中当前日期(时间)函数总结 select now():获取当前日期(包含时分秒) 2.Select date_formate(now(),"格式化") select da ...

  8. mysql rank_在MySQL中实现Rank高级排名函数

    MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名 ...

  9. 在MySQL中实现Rank高级排名函数

    在MySQL中实现Rank高级排名函数 前言 用例表 1.在MySQL中实现普通排名 2.在MySQL中实现并列连续序号排名 3.在MySQL中实现并列非连续序号排名 4.随机获得一条数据 5.判断数 ...

  10. rank()函数 mysql_在MySQL中实现Rank高级排名函数

    在MySQL中实现Rank高级排名函数 MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可 ...

最新文章

  1. 用tarball实现liferay自动安装部署15-复制定制后的catalina.sh
  2. linux ubunt 安装软件的前期准备——更新源的更换
  3. elasticsearch简单操作(一)
  4. phpstorm 2016.3 终极激活方法
  5. MySQL的单表索引优化案例
  6. php 情书,php趣味编程 - php输出笛卡尔情书的秘密
  7. A star 算法 (Python)
  8. 关于Java中被static修饰的静态变量 (类变量)
  9. linux中SUID,SGID和SBIT的奇妙用途
  10. canny算子 轮廓闭合_python实现:prewitt, laplace,sobel,scharr, canny, hed
  11. python笔试题(一)
  12. NSGA-II的算法介绍
  13. 多年iOS开发经验总结
  14. js室内地图开发_支付宝小程序室内地图导航开发-支付宝小程序JS加载esmap地图...
  15. 解决Unable to find a single main class from the following candidates
  16. linux界面安装weblogic12c,Linux安装WebLogic12c
  17. html 图片repeat,html中repeat技术分享
  18. 折纸飞机的12种方法【转】
  19. 二值logit模型的适用条件_你们要的二项Logit模型在这里——离散选择模型之八...
  20. (jsp/html)网页上嵌入播放器

热门文章

  1. DEV gridcontrol设置行与选中行的不同颜色
  2. mysql最高安全级别双一_Mysql 双一配置保证数据0丢失
  3. 维特WT931——制作支持ROS的IMU惯性导航传感器
  4. 打不开eclipse 由于它来自身份不明的开发者
  5. 怎么屏蔽还有照片_华为手机中老是出现不明照片?这些功能一定要注意,尽量将其关闭...
  6. 2022年全球市场MEMS振荡器总体规模、主要生产商、主要地区、产品和应用细分研究报告
  7. 学计算机和英语哪个好考,英语不好,学计算机哪方面比较好?
  8. C语言------进制转换器
  9. 基于GPS经纬度和当地时间计算日落日出时间实现
  10. php 微擎钻石投票二开,[模块插件]微擎钻石投票男神女神公众号投票系统完美运营版其他-(微信)小程序...