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

相关推荐
新知图书1 小时前
MySQL用户授权、收回权限与查看权限
数据库·mysql·安全
文城5211 小时前
Mysql存储过程(学习自用)
数据库·学习·mysql
沉默的煎蛋1 小时前
MyBatis 注解开发详解
java·数据库·mysql·算法·mybatis
C语言扫地僧1 小时前
MySQL 事务及MVCC机制详解
数据库·mysql
小镇cxy1 小时前
MySQL事物,MVCC机制
数据库·mysql
雾里看山2 小时前
【MySQL】 库的操作
android·数据库·笔记·mysql
꧁瀟洒辵1恛꧂3 小时前
从新手到高手的蜕变:MySQL 视图进阶全攻略
数据库·mysql
doubt。15 小时前
【BUUCTF】[RCTF2015]EasySQL1
网络·数据库·笔记·mysql·安全·web安全
小辛学西嘎嘎15 小时前
MVCC在MySQL中实现无锁的原理
数据库·mysql
咩咩大主教19 小时前
Go语言通过Casbin配合MySQL和Gorm实现RBAC访问控制模型
mysql·golang·鉴权·go语言·rbac·abac·casbin