关于 MySQL 嵌套子查询中,无法关联主表字段问题的折中解决方法
今天在工作中写项目的时候,遇到了一个让我感到几乎无解的问题,在转换了思路后,想出了一个折中的解决方案,记录如下 。
其实,问题的场景,非常简单:

文章插图
就是需要查询出上图的数据,红框是从 项目产品表 中查询的2个字段,绿框是从与项目产品表关联的 文章表 中查询出的1个字段 。我希望实现的效果是,获取到项目产品对应的文章提交人数,即该项目产品,有多少人提交了文章 。看似很简单啊,于是我开始撸 SQL 语句了 。
先写个雏形既然在查询项目产品表的时候,希望多查询1列数据,而此列数据是从其他关联表获取的,所以基本实现方式,是使用子查询 。
SELECT s.id, s.name, (SELECT COUNT(*) FROM art_subject_article WHERE subject_id = s.id) AS article_numFROM crm_subject sORDER BY article_num DESC;
获得结果如下:
文章插图
这个 SQL 语句,查询出了项目产品所对应的文章数,下面基于它再做个优化调整,把查询到的文章数量 article_num 变为提交文章的用户数量 member_num 。
再优化一下,意外发生了现在不是直接从文章表中,获取文章数量了,而是需要先根据文章表中的用户ID进行分组,获得分组数据之后,再通过 count(*) 聚合函数,拿到用户数量 。于是继续调整 SQL 如下:
SELECT s.id, s.name, (SELECT count(*) FROM (SELECT mg_userid FROM art_subject_article WHERE subject_id = s.id GROUP BY mg_userid) t) AS member_numFROM crm_subject sORDER BY member_num DESC;
但是,运行却报错了:
文章插图
报错信息说:s.id 字段找不到 。这是一个嵌套的子查询,在嵌套的最内层的子查询中,关联外部表的字段,是无法关联的 。虽然我没找根据,但通过报错信息,也能大致看出一二 。而且,在 DataGrip 中,把鼠标放到 s.id 上面时,也会出现一个提示:

文章插图
虽然这个提示,我也不甚明了,但是感觉上,好像就是在告诉我,你无法关联到外部表的字段 。
好像无解了,转变思路,柳暗花明上面的 SQL 语句,看起来是如此的完美,可是就是有问题、不成立,咋办?
突然,灵机一动,想到一个方案,姑且一试 。既然在嵌套的最内层的子查询中,做 WHERE subject_id = s.id 与主表的字段关联行不通,那么,就不在内层的子查询中做关联,把它提到外层的子查询中去,不就行的通了嘛 。于是,改造 SQL 如下:
SELECT s.id, s.name, (SELECT count(*) FROM (SELECT subject_id, mg_userid FROM art_subject_article GROUP BY subject_id, mg_userid) t WHERE t.subject_id = s.id) AS member_numFROM crm_subject sORDER BY member_num DESC;
主要关注子查询这里的改造,我们可以把这里的子查询做个分解 。首先,可以把子查询看成这样:(SELECT count(*) FROM t WHERE t.subject_id = s.id) AS member_num,把它理解成从 t 表中查询与主表的项目产品有关的记录数量 。
然后,我们再把 t 表看成 (SELECT subject_id, mg_userid FROM art_subject_article GROUP BY subject_id, mg_userid) t,代表从文章表中查询出每个产品对应的用户ID 。
最后把2个子查询,整合起来,就实现了查询项目产品表中,每个产品所对应的提交了文章的用户数量 。
有没有更好的解决方案这个折中的方案,虽然可以解决我的问题,但是,我依然想知道,有没有更好的、更标准的最佳实践 。
并且此方案,也有3点不足:
- 改进前我们是对文章表做项目产品关联查询后再分组,改进后是对文章表做全表扫描后的分组,效率较低,在大数据下的表现不好 。
- 优化方案是基于两层嵌套的子查询进行的,假如需要三层嵌套的子查询,此方案估计又失效了 。
- 此优化方案较为局限,不具有普适性,不能很好的适用于各种业务场景 。
【关于 MySQL 嵌套子查询中,无法关联主表字段问题的折中解决方法】
推荐阅读
- 亚运会|一部关于亚运会的电影,反应市井百姓生活的故事,演员表演真到位
- 新破天一剑宝石镶嵌对应表 新破天一剑宝石
- 2016 广西壮族自治区人口和计划生育条例最新?广西壮族自治区人民代表大会常务委员会关于修改《广西壮族自治区人口和计划生育条例》的决定?
- 关于东北的风俗 东北的习俗
- 关于恐龙的一些小知识
- 关于王姓的来源和历史名人和现状
- 关于“蔓”字多音字组词有哪些 蔓的三个多音字组词
- 荣誉勋章秘籍没法用。关于荣誉勋章秘籍?
- 异界军火商顶点?谁能推荐几本关于军火商的小说,要好看的!?
- 有哪些关于清朝历史的电视剧 清朝皇帝电视剧大全