GROUP_CONCAT + IN 返回结果集只有一个??

前言

前几天在网上摸鱼,遇到了一个新鲜的 SQL 函数 GROUP_CONCAT。之前有用过,但是没有进行深入了解,这次索性就记录一下。

快速入门

GROUP_CONCAT 函数用于将多行数据按照指定的顺序连接成一个字符串。

sql 复制代码
SELECT GROUP_CONCAT(id) FROM `tb_park` WHERE merchant_id=1;

-- 2,3,1

配合 ORDER BY:有序连接

默认情况下,GROUP_CONCAT 函数返回的字符串是 无序的,但是我们可以通过使用 ORDER BY 子句来指定排序规则。

特别注意

在 ORDER BY 子句中 只能使用被连接的列名,不能使用其他列名。

sql 复制代码
SELECT GROUP_CONCAT(id ORDER BY id) FROM `tb_park` WHERE merchant_id=1;

-- 1,2,3

配合 SEPARATOR:指定分隔符

通过使用 SEPARATOR 关键字,可以指定连接后的字符串中的分隔符。

sql 复制代码
SELECT GROUP_CONCAT(id ORDER BY id SEPARATOR '-') FROM `tb_park` WHERE merchant_id=1;

-- 1-2-3

配合 GROUP BY:分组连接

GROUP_CONCAT 函数通常与 GROUP BY 子句一起使用,以便在对结果进行分组时,将每个分组内的值连接成一个字符串。

sql 复制代码
SELECT GROUP_CONCAT(id ORDER BY id) FROM `tb_park` GROUP BY merchant_id;

-- 1,2,3
-- 4,6,8,10,11,12

GROUP_CONCAT + IN 配合使用

那么,现在 GROUP_CONCAT 配合 IN 使用,结果将如何呢?

sql 复制代码
SELECT GROUP_CONCAT(id) FROM `tb_park` WHERE merchant_id=1;

-- 2,3,1
sql 复制代码
SELECT * FROM tb_road_berth_state WHERE park_id IN (
    SELECT GROUP_CONCAT(id) ids FROM `tb_park` WHERE merchant_id=1
);

-- 但是,结果只有 park_id=2,这是为什么???

但是呢,结果集只有 park_id=2 的,这是为什么???

分析原因

这是因为 GROUP_CONCAT 生成的是一个 字符串 ,其中包含了多个值,格式为 '2,3,1'

而 IN 子句期望的是单个值或者一个值列表,格式为 2,3,1

解决方案

要解决这个问题,你可以尝试在 GROUP_CONCAT 函数生成的字符串中使用 FIND_IN_SET 函数,以便将多个值与 IN 子句中的单个值进行比较。

sql 复制代码
SELECT * FROM tb_road_berth_state WHERE FIND_IN_SET(
    park_id, 
    (SELECT GROUP_CONCAT(id) ids FROM `tb_park` WHERE merchant_id=2)
) >0;

-- 完美解决

FIND_IN_SET 函数

如何使用

FIND_IN_SET 函数用于在逗号分隔的字符串列表中查找某个值,并返回其在列表中的位置。该函数的语法如下:

sql 复制代码
FIND_IN_SET(search_value, target_string)

其中,search_value 是要查找的值,target_string 是逗号分隔的字符串列表。

FIND_IN_SET 函数的工作原理是,它会在 target_string 中查找 search_value,并返回其在逗号分隔列表中的位置。如果找到了匹配的值,就会返回其位置;如果没有找到匹配的值,就会返回 0。

以下是一个示例,演示了 FIND_IN_SET 函数的用法:

sql 复制代码
SELECT FIND_IN_SET('b', 'a,b,c,d');

在这个示例中,FIND_IN_SET 函数会在逗号分隔的字符串列表 'a,b,c,d' 中查找 'b',并返回其在列表中的位置,即 2。

对性能方面有没有影响?

使用 FIND_IN_SET 函数可能会对查询性能产生一定的影响,特别是在大型数据集上。这是因为 FIND_IN_SET 函数需要对逗号分隔的字符串列表进行解析和比较,这可能会导致一些额外的计算开销。

另外,FIND_IN_SET 函数在某些情况下可能无法有效地利用索引,尤其是在大型表上。这可能会导致查询性能下降,特别是在需要频繁执行这类查询时。

为了最大程度地减少性能影响,可以考虑以下几点:

  • 确保表上的相关列有适当的索引,以便数据库可以更有效地处理FIND_IN_SET函数。
  • 限制FIND_IN_SET函数生成的字符串长度,避免生成过长的字符串。
  • 定期进行数据库性能优化和索引优化,以确保数据库能够高效地处理这类查询。

总的来说,使用 FIND_IN_SET 函数可能会对查询性能产生一定的影响,但在大多数情况下,这种影响是可以接受的。重点是根据具体情况进行优化,以确保查询能够以最佳性能运行。

写在最后

为了性能考虑,还是老老实实地使用 JOIN 语法吧,别整这些花活!!!

相关推荐
楠枬19 分钟前
MySQL数据的增删改查(一)
数据库·mysql
阿华的代码王国2 小时前
MySQL ------- 索引(B树B+树)
数据库·mysql
liupenglove2 小时前
golang操作mysql利器-gorm
mysql·golang
叫我:松哥3 小时前
基于Python flask的医院管理学院,医生能够增加/删除/修改/删除病人的数据信息,有可视化分析
javascript·后端·python·mysql·信息可视化·flask·bootstrap
单字叶3 小时前
MySQL数据库
数据库·mysql
just-julie3 小时前
MySQL面试题——第一篇
数据库·mysql
这孩子叫逆12 小时前
6. 什么是MySQL的事务?如何在Java中使用Connection接口管理事务?
数据库·mysql
掘根14 小时前
【网络】高级IO——poll版本TCP服务器
网络·数据库·sql·网络协议·tcp/ip·mysql·网络安全
Bear on Toilet15 小时前
初写MySQL四张表:(3/4)
数据库·mysql
无妄啊______15 小时前
mysql笔记9(子查询)
数据库·笔记·mysql