mysql使用GROUP_CONCAT和left join进行联合多表查询,(处理多表查询时,某表数据为空null值处理以及结果集多条数据展示在一行的处理)

mysql使用GROUP_CONCAT和left join进行联合多表查询

(处理多表查询时,某表数据为空null值处理以及结果集多条数据展示在一行的处理)


文章是按照需求分析以及跳坑顺序情景再现的顺序来写的.

如果你不是小白,你可以直接跳到最后看一下代码看个思路.


三个表,分别是

buyer表,记录用户的信息

buyerstags表,记录用户有哪些标签,标签是谁赋予的.是一个用户与标签关系表.通常不用来记录需要显示给UI的数据

tagforbuyer表,直接理解就是标签表,里面是每个标签的信息.由于这个标签是为了买家建立的,所以取名比较长,在本例中,可以直接理解为tag

 

现实应用中,我们常常需要一句话把需要的简单信息查询出来,

所以我们需要联合查询

其中,联合查询,可以直接使用 from多表的方式 也可以使用 left join的方式

下面通过实际操作 来看一下具体的哪些功能需要哪些语法

 


首先 需求是这样的:

查到如下显示效果的信息:

要查询的字段有  

买家id,买家昵称,所拥有的标签名称 (注意 这里的buyerstags只是一个关系表.要查询的时候需要借助此表,但是不展示他的字段)

并且,一个买家有多个标签的时候,我们使用  "标签1,标签2,标签3"这样的 使用一行数据,标签字段使用逗号分隔的方式展示出来

然后,我们想到的是使用多表联合基础查询

来看一下 这个5908买家的所有标签

但是我们想要 家属,微信一般顾客  这样的一行数据  就需要使用的group_concat

运行起来是这样的

但是这样就有一个问题 那就是 如果你where=条件的时候会返回一条数据,那么where in的时候 就也会合并到一行 如下:

 

可以看到,显然不是我们要的结果,因为我们需要把这三个买家的信息和他们的标签分别展示出来.那我们就需要加一个group by,不然的话,group_concat默认是把所有结果表述成一行

好了 看起来好像没有问题了. 不过注意  这里没有5910的信息呀? 为什么呢  因为   在where条件中,这种联表查询的时候 有一个条件的不符合,就不会返回结果.

这条语句中,当在检索买家的标签关系表  tagforbuyer的时候,没有关于5910的标签关联信息,所以,匹配是空的,就没有返回这一条结果.

后来  我摸索着,在where条件中 使用ifnull, if  在里面子集select等等多种多种方式(因为我也是半路出家) 最后都失败了.

然后重新摸起书,上谷歌翻资料 想到了left join

这个left join的特点是,当你查询的时候,如果前面的表有数据,返回前面查询表的数据,后面的如果匹配不上,就是null   这好像就是我们要的结果了.

于是改用left join

这里我们又要注意了.tagid,tagname的关系,  比如结果第一行  id就一个,name是2个  显然id是错误的,因为没有用group_concat

改一下:

那这样就对了.

由于我们不需要使用tagid字段 所以可以给他去掉,也是不影响结果的,只要关系语句中关系表述正确即可

最后,我们在where条件中,加入我们想要搜索的买家的id集合

结果是正确的.

但是现实使用中,我们可能还需要使用关联的拼音检索表,根据电话查询等场景,所以 我们还需要在 where buyer.buyerid in 里面变成我们自己的查询语句 比如

或者增加根据电话查询(如果不在应用程序判断给定的内容是字符串还是数字的话,直接加条件,也不会太影响性能)

如果想把数字和字母的检索分开的话,可以在查询数据库之前,应用程序判断查询的条件,比如判断了是数字检索 那么就查询mobile字段

这样查询就简单了.

这两种查询,返回的结果如果放在where in语句中,就相当于是  1,2,3,4,5  这样的数据

所以增加了拼音和电话检索的语句是这样的

圈选位置就是代替了之前的  5908,5909,5910

 

查询示例:

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
从多张表中查询数据等价于使用左连接(left join)连接其他表。左连接是一种联接操作,它返回左表中的所有记录,而右表中与左表匹配的记录。如果左表中的一条记录对应右表中的多条记录,那么查询结果中右表的数据也只会显示一条。如果想要将右表的多条记录都显示出来,可以使用group_concat()函数将字段用逗号隔开显示在一条记录上。因此,当存在一对多关系,需要进行适当的处理。\[1\]左外连接(left outer join)是一种特殊的左连接,它返回左表中的所有记录,而右表中与左表匹配的记录,如果右表中没有匹配的记录,则显示为NULL。\[2\]普通的联接(inner join)是一种联接操作,它返回在两个表中都存在的记录。\[3\]因此,从多张表中查询数据等价于使用左连接(left join)连接其他表。 #### 引用[.reference_title] - *1* [mysql left join 左连接查询关联n多张表](https://blog.csdn.net/weixin_39720181/article/details/111529517)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [SQL left[right] join多张表和from多张表的区别](https://blog.csdn.net/Andrew_Chenwq/article/details/122647588)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Afterwards_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值