【问题标题】:In MySQL, how do I join two fields in one table to the same table's primary key? [closed]在 MySQL 中,如何将一张表中的两个字段连接到同一张表的主键? [关闭]
【发布时间】:2022-07-16 01:40:41
【问题描述】:

我正在 64 位 Windows 上使用 MySQL 后端(版本 5.7.19)和 LibreOffice Base 前端(版本 7.0.6.2 x64)。我有一张表格,列出了具有主键 ID 的人员。我还有一个工作订单表,其中有一个“输入者”字段和一个“审核者”字段,这两个字段都需要存储完成这些任务的人员的 ID。如果我想在一个表中有两个外键指向同一个表的主键,我的 SELECT 语句应该是什么样子?

在我的例子中,我有一个表“personnel”,其中包含两个字段,ID 作为主键,因此:

ID Name
1 John Smith
2 John Adams
3 Samuel Adams

可以这样创建和填充:

CREATE TABLE orders(
workorder int(10) unsigned NOT NULL AUTO_INCREMENT,
entered_by int(10) unsigned NOT NULL,
reviewed_by int(10) unsigned NOT NULL, 
PRIMARY KEY (workorder),
FOREIGN KEY (entered_by) REFERENCES personnel(id),
FOREIGN KEY (reviewed_by) REFERENCES personnel(id)
);
ALTER TABLE orders AUTO_INCREMENT = 1;
INSERT INTO personnel(name) VALUES('John Smith');
INSERT INTO personnel(name) VALUES('John Adams');
INSERT INTO personnel(name) VALUES('Samuel Adams');

另外,一个表 'orders' 包含三个字段,其中 enter_by 和 review_by 作为 person.id 的外键

workorder entered_by reviewed_by
1 2 3
2 3 1

可以这样创建和填充:

CREATE TABLE orders(
workorder int(10) unsigned NOT NULL AUTO_INCREMENT,
entered_by int(10) unsigned NOT NULL,
reviewed_by int(10) unsigned NOT NULL, 
PRIMARY KEY (workorder),
FOREIGN KEY (entered_by) REFERENCES personnel(id),
FOREIGN KEY (reviewed_by) REFERENCES personnel(id)
);
INSERT INTO orders(entered_by, reviewed_by) VALUES (2,3);
INSERT INTO orders(entered_by, reviewed_by) VALUES (3,1);

我知道怎么做

SELECT workorder, personnel.name AS entered FROM orders JOIN personnel ON personnel.id = orders.entered_by ORDER BY orders.workorder;

导致 |工单|进入 | |-----------|---------| | 1 |约翰亚当斯 | | 2 |塞缪尔·亚当斯 |

怎么做

SELECT workorder, personnel.name AS entered FROM orders JOIN personnel ON personnel.id = orders.entered_by ORDER BY orders.workorder;

产生:

workorder reviewed
1 Samuel Adams
2 John Smith

但我不确定如何将它们放入单个查询中,以便我得到:

workorder entered reviewed
1 John Adams Samuel Adams
2 Samuel Adams John Smith

【问题讨论】:

  • 可以在一个表中有两个外键指向同一个表的主键吗? 可以。这种情况很常见(sender-receiver、homeplayer-guest 等)
  • 请在代码问题中给出minimal reproducible example--剪切&粘贴&可运行代码&示例输入;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。对于 SQL 包括 DDL 和表格初始化代码。对于包含最少代码的调试,您可以提供的代码是您显示的代码可以通过您显示的代码扩展为不正常。 How to Ask Help center 当你得到一个出乎意料的结果时,暂停你的总体目标,切到第一个子表达式,结果出乎意料,然后​​说出你的预期和原因,并通过文档证明是合理的。 (调试基础。)
  • 您的帖子属于评论的内容。但不是多余的,比如要求重新开放。 help center 您可以通过Meta Stack OverflowMeta Stack Exchange 的问答进行研究和提问(如果已研究和针对主题)重新提问和您的帖子——但要注意“元效应”。我的最后一条评论给出了minimal reproducible example 的摘要,但你没有做很多部分,比如第一个。 PS 问 1 个具体研究过的非重复问题。你的是啥呢?目前尚不清楚问号句子要求什么(SELECTing 不使用 FK),它不是帖子标题问题或隐含问题“如何将它们放入单个查询”。加入一个表两次是一个常见问题。
  • 表(基础、视图和查询结果)表示关系(船舶)/关联。 FK 约束通常被称为“关系(船)”,但它们不是。他们说子行作为 PK/UNIQUE 出现在其他地方。表含义是查询的必要和充分条件。查询时不需要约束——包括 CK、PK 和 FK。它们是表关系(船)/关联选择的结果以及可能出现的情况/状态。它们是为了由 DBMS 强制执行完整性。 (但是当约束成立时,其他查询返回的结果与不假定约束的查询相同。)

标签: mysql join foreign-keys


【解决方案1】:

是的,根据关系代数,每对表之间都可以有多个关系。

例如,这个案例的典型例子是一个money_transfer 表,它记录了资金从一个账户流向另一个账户。在这种情况下,该表将有两个针对 account 表的外键:一个指示资金的来源,另一个指示资金的去向。

其他表对之间可以有更多的关系。我见过有很多 FK 的授权和审计案例。

例如,要求规定应用程序需要记录谁输入了数据、谁验证了数据、谁接受了数据以及谁执行了交易;有时它甚至有“一级批准”(金额超过 1 万美元)和“二级批准”(金额超过 10 万美元)。

编辑 - 多次加入同一个表

根据要求,当多次加入同一个表时,您需要为表的每个“实例”分配不同的名称。通常这是通过根据角色为每个表实例添加别名来完成的。

在这种情况下,角色是“输入者”和“审核者”,因此查询可以分别使用别名er。查询可以采用以下形式:

select o.*, e.name, r.name
from workorders o
join personnel e on e.id = o.entered_by
join personnel r on r.id = o.reviewed_by

【讨论】:

  • @agerber85 请编辑问题并添加几行示例数据和预期结果。
  • @agerber85 是的,这是有道理的。如果您想包含所有行,即使是带有空值的行。然后在我的查询中用left join 替换join。当然,e.name 和/或 r.name 将显示为 null,因为没有匹配项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-08
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多