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 语法吧,别整这些花活!!!

相关推荐
.Shu.1 小时前
Mysql InnoDB 底层架构设计、功能、原理、源码系列合集【五、InnoDB 高阶机制与实战调优】
数据库·mysql
新法国菜3 小时前
MySql知识梳理之DDL语句
数据库·mysql
大只鹅5 小时前
Centos7.9 Docker26容器化部署 MySql9.4 一主一从的同步复制部署
mysql·centos
叁沐6 小时前
MySQL 28 读写分离有哪些坑?
mysql
DarkAthena6 小时前
【GaussDB】使用MySQL客户端连接到GaussDB的M-Compatibility数据库
数据库·mysql·gaussdb
帧栈16 小时前
开发避坑指南(29):微信昵称特殊字符存储异常修复方案
java·mysql
瓜酷月..16 小时前
MySQL的高可用+MHA
数据库·mysql
苹果醋320 小时前
Java并发编程-Java内存模型(JMM)
java·运维·spring boot·mysql·nginx
翔云12345621 小时前
Python 中 SQLAlchemy 和 MySQLdb 的关系
数据库·python·mysql
叁沐1 天前
MySQL 27 主库出问题了,从库怎么办?
mysql