查询需求:表A类似字典表,表B为实体表,表B的元素存储着表A的多个id用","隔开;使用sql语句直接如下图效果
SELECT GROUP_CONCAT(sd.name) deptname ,su.id,su.DEPTID
FROM
sys_dept sd LEFT JOIN sys_user su ON FIND_IN_SET(sd.id,su.DEPTID)>0
GROUP BY su.id
group_concat(),手册上说明:该函数返回带有来自一个组的连接的非NULL值的字符串结果
通俗点理解,其实是这样的:group_concat()会计算哪些行属于同一组,将属于同一组的列显示出来。
要返回哪些列,由函数参数(就是字段名)决定。分组必须有个标准,就是根据group by指定的列进行分组。
如果没有进行分组,则得到的结果集会因为group_concat函数的原因全部归并到同一组去;
find_in_set() :
1. 假如字符串str在由N子链组成的字符串列表strlist中,则返回值的范围在1到N之间。
2. 一个字符串列表就是一个由一些被‘,’符号分开的自链组成的字符串。
3. 如果第一个参数是一个常数字符串,而第二个是typeSET列,则FIND_IN_SET()函数被优化,使用比特计算。
4. 如果str不在strlist或strlist为空字符串,则返回值为0。
5. 如任意一个参数为NULL,则返回值为NULL。这个函数在第一个参数包含一个逗号(‘,’)时将无法正常运行。
strlist:一个由英文逗号“,”链接的字符串,例如:"a,b,c,d",该字符串形式上类似于SET类型的值被逗号给链接起来。
示例:SELECT FIND_IN_SET('b','a,b,c,d');//返回值为2,即第2个值
另外谈到了 find_in_set()函数的话,就谈下最近一直在用的locate()函数的区别
1、LOCATE(substr,str) , LOCATE(substr,str,pos)
第一个语法返回字符串 str中子字符串substr的第一个出现位置。第二个语法返回字符串str中子字符串substr的第一个出现位置, 起始位置在pos。如若substr 不在str中,则返回值为0。
SELECT LOCATE("a","A") locate;-- 注意:该函数不区分大小写
SELECT LOCATE('bar', 'foobarbar') locate;
SELECT LOCATE('xbar', 'foobar') locate;-- 未找到值
SELECT LOCATE('bar', 'foobarbar',5) locate;
SELECT LOCATE(null, 'foobarbar',5) locate;-- 当某个参数为null,则返回NULL
结果为:
2、FIND_IN_SET(str,strlist)
假如字符串str 在由N 子链组成的字符串列表strlist 中, 则返回值的范围在 1 到N 之间 。一个字符串列表就是一个由一些被‘,’符号分开的自链组成的字符串。如果第一个参数是一个常数字符串,而第二个是type SET列,则 FIND_IN_SET() 函数被优化,使用比特计算。如果str不在strlist 或strlist 为空字符串,则返回值为 0 。如任意一个参数为NULL,则返回值为 NULL。 这个函数在第一个参数包含一个逗号(‘,’)时将无法正常运行。
SELECT FIND_IN_SET("A","a") find;-- 不区分大小写
SELECT FIND_IN_SET("A","A") find;
SELECT FIND_IN_SET("A","AB") find;
SELECT FIND_IN_SET("A","AB,qw") find;
SELECT FIND_IN_SET(NULL,"AB") find;
结果为:
比较结果显示我这边的sql语句中的链接条件只能使用find_in_set()函数,如果使用locate()的话,结果会有重复。