如何从具有多个关联的两个 MySQL 表中检索数据
Posted
技术标签:
【中文标题】如何从具有多个关联的两个 MySQL 表中检索数据【英文标题】:How to retrieve data from two MySQL tables with multiple associations 【发布时间】:2021-11-22 10:02:54 【问题描述】:我得到了这两个表,其中一个表具有第二个表的多个外键。
表rankings
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| search_text | varchar(255) | YES | MUL | NULL | |
| first_item_id | bigint(20) | YES | MUL | NULL | |
| second_item_id | bigint(20) | YES | MUL | NULL | |
| third_item_id | bigint(20) | YES | MUL | NULL | |
| forth_item_id | bigint(20) | YES | MUL | NULL | |
+----------------+--------------+------+-----+---------+----------------+
表item
+---------------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| item_code | varchar(255) | YES | MUL | NULL | |
+----------------+--------------+------+-----+---------+---------------------------+
一个ranking
记录可能使用first_item_id
、second_item_id
、third_item_id
或forth_item_id
字段与item
表有多个关联。我想用相应的item_code
而不是item.id
检索ranking
记录。如果我有大量数据,最有效的方法是什么?
PS:item.id
与 first_item_id
... tenth_item_id
有 10 个关联。我正在使用 Rails ActiveRecord
ORM。任何解决方法都可以。
样本数据ranking
SELECT id,search_text,first_item_id as first,second_item_id as second,third_item_id as third,forth_item_id as forth from rankings limit 10;
+----+-------------+-------+--------+-------+-------+
| id | search_text | first | second | third | forth |
+----+-------------+-------+--------+-------+-------+
| 1 | test 1 | 1 | 2 | 3 | 4 |
| 2 | test 2 | 1 | 2 | 3 | 4 |
| 3 | test 3 | 1 | 2 | 3 | 4 |
| 4 | test 4 | 1 | 2 | 3 | 4 |
+----+-------------+-------+--------+-------+-------+
item
数据示例
SELECT id,item_code from items limit 5;
+--------+------------+
| id | item_code |
+--------+------------+
| 1 | 125659 |
| 2 | 125660 |
| 3 | 125661 |
| 4 | 125662 |
+--------+------------+
预期数据
+----+-------------+-------+--------+-------+-------+
| id | search_text | first | second | third | forth |
+----+-------------+-------+--------+-------+-------+
| 1 | test 1 | 125659| 125660 | 125661| 125662|
| 2 | test 2 | 125659| 125660 | 125661| 125662|
| 3 | test 3 | 125659| 125660 | 125661| 125662|
| 4 | test 4 | 125659| 125660 | 125661| 125662|
+----+-------------+-------+--------+-------+-------+
【问题讨论】:
一般来说,你最好的选择是在这里加入“item”四次。四是一个合理的数字。如果从性能的角度来看这太昂贵,请确保您有适当的索引或重新考虑您的数据模型。但是,如果这只是一个简化的情况,并且您有几十个项目列,您可以 UNPIVOT、加入,然后 PIVOT。其语法将取决于您的 DBMS。 不,同一个表有 10 个关联,我的 DBMS 是 mysql。有什么建议吗? 您能提供样本数据和预期结果吗? @Ragnar921 10 有点灰色地带。 MySQL 似乎不支持任何不错的 unpivot/pivot 函数。因此,您将执行 UNION 以取消透视,然后加入,然后执行一系列 CASE 语句以进行透视。不过,这对数据模型来说有点难闻,如果你规范化这个“排名”表的生活会更容易。 @Austin 更新了问题,请检查。 【参考方案1】:多次(甚至很多次)加入表应该不是问题,因为您是在主键上加入的,即您有一个将要使用的索引。
select
r.id,
r.search_text,
i1.item_code as item_code_1,
i2.item_code as item_code_2,
i3.item_code as item_code_3,
i4.item_code as item_code_4
from rankings r
left join item i1 on i1.id = r.first_item_id
left join item i2 on i2.id = r.second_item_id
left join item i3 on i3.id = r.third_item_id
left join item i4 on i4.id = r.forth_item_id
order by r.id;
我在这里使用外连接,因为您的所有项目列都可以为空。
【讨论】:
以上是关于如何从具有多个关联的两个 MySQL 表中检索数据的主要内容,如果未能解决你的问题,请参考以下文章