数据库中某个表中的某个字段的值是用逗号隔开的多个值,根据逗号拆分并从另一个表中查出数据返回

本文深入讲解了使用FIND_IN_SET和group_concat函数进行复杂查询的技巧,通过具体案例解析了如何利用这两个函数处理多表关联数据,提升SQL查询效率。

两个表的结构如下

a表在这里插入图片描述
b 表在这里插入图片描述
关系说明
b.teacherid = a . user_id

查询思路 :

  1. FIND_IN_SET(str,strlist),该函数用于判断 str 是否在 strlist 中,如果是,作为条件,返回对应数据,如果str不在strlist 或strlist 为空字符串,则返回值为 0 。

  2. group_concat(),官方:该函数返回带有来自一个组的连接的非NULL值的字符串结果。
    通俗点理解:group_concat()会计算哪些行属于同一组,将属于同一组的列按照一定的拼接规则拼接好显示出来。形象的来说就是把列里的内容转化到了行里。

效果图
在这里插入图片描述

<think>嗯,用户的问题是关于MySQL数据库中如何关联查询两个,其中A的dataID字段是用逗号分隔存储了B的appId。这种情况应该如何处理呢?首先,我需要回忆一下MySQL中处理逗号分隔字符串的方法。 首先,用户提到的是两个,A和B。A的dataID字段存储的是多个B的appId,以逗号分隔。比如,dataID可能是"1,2,3",而B中的appId对应这些。用户想要关联这两个进行查询,可能需要根据这些ID获取对应的B信息。 通常情况下,关联两个是通过外键或者JOIN操作,但这里A的dataID字段存储的是多个,用逗号分隔,这违反了第一范式,导致难以直接使用JOIN。这种情况下,如何处理呢? 我记得MySQL一个叫做FIND_IN_SET,可以用来查找某个是否在逗号分隔的字符串中。比如,FIND_IN_SET(b.appId, a.dataID) > 0,这样可以找到匹配的记录。这样的话,可以通过这个函来进行JOIN操作。 不过,这种方法可能效率不高,尤其是当数据量大的时候,因为FIND_IN_SET不能有效利用索引,会导致全扫描。用户可能需要考虑数据结构的优化,比如将逗号分隔的数据拆分成多行存储,或者使用关联来建立多对多的关系。 外,还可以使用LIKE来进行模糊匹配,比如CONCAT(',', a.dataID, ',') LIKE CONCAT('%,', b.appId, ',%'),这样可以避免部分匹配的问题,比如appId为1时,不会错误匹配到10这种情况。不过同样存在性能问题。 所以,可能的解决方案有两种:一种是使用FIND_IN_SET或者LIKE进行关联,但需要注意性能;一种是建议用户修改数据结构,使用第三张关联来存储关系,这样可以通过标准的JOIN操作来提高效率。 用户可能没有权限或者暂时无法修改结构,所以需要给出临时的查询方法。但如果长期来看,建议优化数据结构,避免使用逗号分隔存储多个,这样更符合数据库设计的规范,也便于维护和查询。 总结一下,回答应该包括两种方法:使用FIND_IN_SET进行关联查询指出性能问题;以及建议优化数据结构,使用关联。同时,给出具体的SQL示例,帮助用户理解如何操作。</think>在 MySQL 中,当某个字段逗号分隔存储多个关联时,可以通过以下两种方式实现关联查询: --- ### **方式一:使用 FIND_IN_SET 函** ```sql SELECT a.*, b.* FROM a AS a LEFT JOIN b AS b ON FIND_IN_SET(b.appId, a.dataID) > 0 ``` #### 特点: - ✅ 简单直接,适合数据量较小的情况 - ❌ 无法使用索引,大数据量时性能差 - ❌ 无法保证数据完整性(如包含无效的 appId) --- ### **方式二:数据规范化改造(强烈推荐)** #### 步骤: 1. 新建关联 `a_b_relation` ```sql CREATE TABLE a_b_relation ( a_id INT NOT NULL, appId INT NOT NULL, PRIMARY KEY (a_id, appId) ); ``` 2. 将原数据拆分存入关联 ```sql -- 通过 SUBSTRING_INDEX 拆分字符串 INSERT INTO a_b_relation (a_id, appId) SELECT a.id, SUBSTRING_INDEX(SUBSTRING_INDEX(a.dataID, ',', n), ',', -1) AS appId FROM a AS a JOIN (SELECT 1 n UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) numbers ON CHAR_LENGTH(dataID) - CHAR_LENGTH(REPLACE(dataID, ',', '')) >= n - 1; ``` 3. 标准 JOIN 查询 ```sql SELECT a.*, b.* FROM a AS a JOIN a_b_relation AS r ON a.id = r.a_id JOIN b AS b ON r.appId = b.appId ``` #### 优势: ✅ 支持索引优化 ✅ 确保数据完整性 ✅ 便于统计分析和复杂查询 ✅ 符合数据库设计范式 --- ### **建议选择:** - 临时查询数据 → 使用 `FIND_IN_SET` - 长期使用系统 → 必须进行规范化改造 实际项目中应尽量避免在字段中存储逗号分隔,这种反范式设计会导致查询效率低下、维护困难等问题。建议尽早进行数据结构优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值