mysql - 从多个表中获取相关行而不使用所有组合

Posted

技术标签:

【中文标题】mysql - 从多个表中获取相关行而不使用所有组合【英文标题】:mysql - fetch related rows from multiple tables without all combinations 【发布时间】:2020-09-15 19:59:12 【问题描述】:

假设我有一个主表 record,它有 2 个相关表 fieldscomments

CREATE TABLE record (id int primary key, name varchar(20))
CREATE TABLE fields (record_id int, name varchar(20), val int)
CREATE TABLE comments (record_id int, who varchar(20), comment text)

我想运行一个查询来获取一组记录并获取该记录的所有相关字段,并获取与该记录相关的所有 cmets。

如果我使用左连接来确保获得记录,我会使用:

select * from record
     left join fields on (fields.record_id = record.id)
     left join comments on (comments.record_id = record.id)
     order by record.id

问题是,我为每条记录返回 n * m 行,其中 n 是字段数,m 是 cmets 数。我想取回 n + m 行(有意义的是,在返回 cmets 时字段列全部为空,而在返回字段时 cmets 列全部为空)。除了插入虚拟评论和虚拟字段来加入之外,还有其他方法可以使这项工作吗?我非常希望不必为每条记录执行额外的查询。

我想这不是 mysql 特定的,但这就是我在我的应用程序中使用的。

【问题讨论】:

【参考方案1】:

我为每条记录返回 n * m 行,其中 n 是字段数,m 是 cmets 数。我想取回 n + m 行

    SELECT * 
    FROM record
    LEFT JOIN fields ON (fields.record_id = record.id) /* maybe INNER JOIN ? */
    LEFT JOIN comments ON (1=0)
UNION ALL
    SELECT * 
    FROM record
    LEFT JOIN fields ON (1=0)
    LEFT JOIN comments ON (comments.record_id = record.id) /* maybe INNER JOIN ? */
-- ORDER BY record.id

【讨论】:

我要补充一点,我希望数据一起返回,所以我必须根据数据中的公共字段进行排序。不幸的是,(在真实数据上)我不得不使用列索引来排序,这有点可怕。【参考方案2】:

我想取回 n + m 行(有意义的是在返回 cmets 时字段列全部为空,而在返回字段时 cmets 列全部为空)

一个选项在子查询中使用union all,然后是left join

select *
from record r
left join (
    select record_id, name, val, null who, null comment from fields
    union all record_id, select null, null, who, comment from comments
) x on x.record_id = r.record_id

不过,这是一个奇怪的结果集。

【讨论】:

以上是关于mysql - 从多个表中获取相关行而不使用所有组合的主要内容,如果未能解决你的问题,请参考以下文章

组合多个 mySQL 行而不重复

如何在 React Hooks 中向表中添加行而不重复?

无法单独选择行而不分组

从页面中删除行而不刷新页面

从 .NET 文本/闪烁框读取行而不使用太多内存?

显示所有textarea行而不滚动[重复]