MySQL JOIN 只返回第一个匹配

Posted

技术标签:

【中文标题】MySQL JOIN 只返回第一个匹配【英文标题】:MySQL JOIN only returns first match 【发布时间】:2016-03-16 16:28:22 【问题描述】:

我正在尝试使用此联接返回多行用户 ID,在这些用户 ID 中发现它们位于另一个表中特定行的收件人列表中。

SELECT a.`USER_ID`
FROM Users a
INNER JOIN Lists b ON a.`USER_ID` = b.`RECIP`
WHERE a.`PARENT` = '1'
AND b.`LIST_ID` = '210'

上面的查询应该返回 5 行,因为 RECIP 中有 5 个匹配项,但我只看到 1 个结果,这是 RECIP 中的第一个匹配项

在表'Lists'中,行LIST_ID '210' RECIP 包含'22,33,40,42,45' 因此,我希望查询会从表“用户”中返回 5 行,因为所有这些 USER_ID 都存在:

USER_ID 22

USER_ID 33

USER_ID 40

USER_ID 42

USER_ID 45

但我只得到一个结果:

USER_ID 22

我已经尝试了很多方法(SELECT DISTINCT...,GROUP BY a.ID),但我没有取得任何进展。老实说,我仍在努力了解连接。

谁能给点建议?

【问题讨论】:

这个b.ID = '210' 是限制来自Lists 表的匹配记录的谓词。 是的,我想你想过滤 a 中的 ID 而不是 b 【参考方案1】:

问题是recip 字段包含列表中的数字'22,33,40,42,45'。如果此字符串与a.USER_ID = b.RECIP 中的数字匹配,则该字符串将被评估为数字 22,因为逗号不是 mysql 中有效数字表达式的一部分,因此 mysql 在第一次出现逗号时停止评估字符串。

最好的解决方案是规范化您的数据结构并将recip 中的每个值存储在其自己的记录中。

快速的解决方案是在连接表达式中使用find_in_set() 函数:

SELECT a.`USER_ID`
FROM Users a
INNER JOIN Lists b ON find_in_set(a.`USER_ID`,b.`RECIP`)>0
WHERE a.`PARENT` = '1'
AND b.`LIST_ID` = '210'

【讨论】:

太好了,谢谢。在较小的 RECIP 值上完美工作,但我需要设计一个更有效的解决方案,因为目前某些 RECIP 列表包含超过 10,000 个 ID 如前所述,最好的解决方案是规范化您的数据结构。我的猜测是您遵循了快速解决方案。 暂时可以。但我保证我会规范化数据结构以获得长期利益! :)【参考方案2】:

因此,您只过滤了第二个表中的一行:

AND b.`ID` = '210'

以下其中一项应该有效,具体取决于您的数据,但您没有显示任何内容:

SELECT a.`ID`
FROM Users a
INNER JOIN Lists b ON a.`ID` = b.`RECIP`
WHERE a.`PARENT` = '1'

SELECT a.`ID`
FROM Users a
LEFT JOIN Lists b ON a.`ID` = b.`RECIP`
WHERE a.`PARENT` = '1'

【讨论】:

以上是关于MySQL JOIN 只返回第一个匹配的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 数据库中 left outer join 和 left join 啥区别?

mysql join

为啥 NSBundle 只返回与用户的语言偏好匹配的包中存在的第一个本地化而不是所有匹配?

26.MySQL中的内连接INNER JOIN

MySQL返回连接表的第一行

NSPredicate ANY 只返回与字符串列表中第一个元素的关键字匹配的记录