在单个 MySQL 查询中,我可以从具有主键数组的字段返回字符串数组吗

Posted

技术标签:

【中文标题】在单个 MySQL 查询中,我可以从具有主键数组的字段返回字符串数组吗【英文标题】:In a single MySQL query, can I return a string array from a field with an array of primary keys 【发布时间】:2018-07-26 23:13:26 【问题描述】:

使用 mysql,如果我有一个表 Topic 的字段 who 使用表 Users 中的主键 uid

| aid |  subject |  who    |
---------------------------
| 1   |  foo     | 1, 2, 3 |
| 2   |  bar     | 1, 3    |
| 3   |  spec    | 1, 2, 4 |
| 4   |  sauce   | 3       |

还有一张桌子Users

 | uid |  fname  |  lname  |
 ---------------------------
 | 1  |  Jack    | Black   |
 | 2  |  Jill    | White   |
 | 3  |  Tom     | Grey    |
 | 4  |  Dick    | Brown   |

我想查询谁与每个主题相关联,按名称,我的结果应该如下所示:

 | aid |  subject |  who    
    1      foo      Jack Black, Jill White, Tom Grey
    2      bar      Jack Black, Tom Grey
    3      spec     Jack Black, Jill White, Dick Brown
    4      sauce    Tom Grey

我认为查询应该类似于:

SELECT GROUP_CONCAT(namearray SEPARATOR ', ') 
FROM 
  (SELECT CONCAT(fname, ' ', lname) AS namearray 
   FROM Users 
   WHERE uid IN (1,2,3) ORDER BY lname) AS tWho

IN 子句中手动输入 1,2,3 时有效。我什至不知道从哪里开始将字段who 插入IN 子句。

这可以在一个查询中完成吗?或者我是否需要获取带有who 数字的查询结果,并执行第二次查询以获得最终结果?

【问题讨论】:

【参考方案1】:

尝试使用FIND_IN_SET加入:

SELECT
    t.aid,
    t.subject,
    GROUP_CONCAT(u.fname, ' ', u.lname) AS who
FROM Topic t
LEFT JOIN Users u
    ON FIND_IN_SET(u.uid, REPLACE(t.who, ' ', '')) > 0
GROUP BY
    t.aid,
    t.subject;

Demo

从概念上讲,例如,通过将 foo 主题 CSV 列表 1, 2, 3 加入用户表,上述查询是有效的。这会产生以下中间结果:

aid | subject | who | full name
1   | aid     | 1   | Jack Black
1   | aid     | 2   | Jill White
1   | aid     | 3   | Tom Grey

然后,我们按主题对连接进行分组,再次以该主题的单个记录以及所有匹配用户的 CSV 字符串结束。

另一个注意事项是,我们需要从您的 who CSV 字符串中删除空格,以便 FIND_IN_SET 按预期工作,因此您会在查询中看到对 REPLACE 的调用。

【讨论】:

哇,有很多概念在发生,尤其是在ON 子句中。但我测试了它,它有效!非常感谢! @Sablefoste 您想要对 CSV 列表中的名称进行特定排序吗? 是的,既然您提到了它,我正计划将按 lname 的排序 ASC 添加到子查询中。不过,我不确定FIND_IN_SET 会去哪里。 如果您决定要订购 CSV 列表,您可以在GROUP_CONCAT 中添加一个ORDER BY 子句。 非常感谢@Tim!我刚刚在这里也发现了这一点:***.com/a/995383/1408137 非常感谢您的帮助!

以上是关于在单个 MySQL 查询中,我可以从具有主键数组的字段返回字符串数组吗的主要内容,如果未能解决你的问题,请参考以下文章

单个查询从具有不同列的多个表中获取记录

如何从单个 MySQL 查询中获取 Parent 的所有子记录 [重复]

MySql在一个查询中获取逗号分隔的主键

MySQL 优化查询,其中主键也在几乎相同的选择中

在 MySQL 中,如何编写 INSERT-INTO-VALUES 查询,以便在已存在具有相同主键值的记录时将其静默丢弃?

MySQL ----- 组合查询 UNION(十五)