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

相关推荐
Stara05112 小时前
Git推送+拉去+uwsgi+Nginx服务器部署项目
git·python·mysql·nginx·gitee·github·uwsgi
不爱学习的啊Biao3 小时前
初识mysql数据库
数据库·mysql·oracle
是桃萌萌鸭~5 小时前
mysqldbcompare 使用及参数详解
数据库·mysql
小草儿7995 小时前
gbase8s之mysql的show命令实现
数据库·mysql
daiyang123...7 小时前
MySQL【知识改变命运】11
android·数据库·mysql
licy__9 小时前
正则表达式语法详解(python)
数据库·mysql·正则表达式
zhangshengqiang16811 小时前
Linux下安装mysql8.0版本
linux·mysql
Karoku06611 小时前
【企业级分布式系统】ELK-企业级日志分析系统
运维·数据库·redis·mysql·elk·缓存
FLGB11 小时前
Docker 安装单机版mysql 并持久化数据
mysql·docker·容器