简体   繁体   English

SQL Select语句:一个孩子-两个父母(两个不同的FK)

[英]SQL Select Statement: One Child - Two Parents (two different FK)

I have the situation where the best to explain it is through the following scenario: 我遇到的情况最好通过以下情况来解释:

  • where a Child record has two Parent s (Mother and Father) Child记录有两个Parent (母亲和父亲)的地方

If you later to read this post consider the option to apply the self-referencing tables scenario, it is not necessary, there are no neither grandfathers nor grandsons. 如果您以后要阅读此文章,请考虑应用self-referencing tables方案的选项,则没有必要,既没有祖父也没有孙子。

About the parent it is defined how: 关于父级 ,定义方式:

CREATE TABLE IF NOT EXISTS parent(
  code varchar(3),
  name varchar(10),
  PRIMARY KEY(code)
)ENGINE=INNODB;

The records are inserted how: 记录如何插入:

INSERT INTO parent(code,name) VALUES('001','Mary');
INSERT INTO parent(code,name) VALUES('002','Joseph');
INSERT INTO parent(code,name) VALUES('003','Adan');
INSERT INTO parent(code,name) VALUES('004','Eva');
INSERT INTO parent(code,name) VALUES('005','Ana');
INSERT INTO parent(code,name) VALUES('006','Elcana');

And the select query works how is expected: select查询的工作方式如何:

mysql> select * from parent;
+------+--------+
| code | name   |
+------+--------+
| 001  | Mary   |
| 002  | Joseph |
| 003  | Adan   |
| 004  | Eva    |
| 005  | Ana    |
| 006  | Elcana |
+------+--------+
6 rows in set (0.01 sec)

About the child it is defined how: 关于孩子,它定义了如何:

CREATE TABLE IF NOT EXISTS child(
  code varchar(3),
  name varchar(10),
  PRIMARY KEY(code),
  mother_code varchar(3),
  father_code varchar(3),
  FOREIGN KEY fk_mother_code(mother_code) REFERENCES parent(code),
  FOREIGN KEY fk_father_code(father_code) REFERENCES parent(code)
)ENGINE=INNODB;

Observation: from above observe the Child expects two PK s from the Parent (assume that must be different) through two FK s. 观察:从上面观察, Child期望Parent通过两个FK来获得两个 PK (假定必须不同)。

The records are inserted how: 记录如何插入:

INSERT INTO child(code, name, mother_code, father_code) VALUES('001','Jesus', '001', '002');
INSERT INTO child(code, name, mother_code, father_code) VALUES('002','Cain', '003', '004');
INSERT INTO child(code, name, mother_code, father_code) VALUES('003','Abel', '003', '004');
INSERT INTO child(code, name, mother_code, father_code) VALUES('004','Set', '003', '004');
INSERT INTO child(code, name, mother_code, father_code) VALUES('005','Samuel', '005', '006');

And the select query works how is expected: select查询的工作方式如何:

mysql> select * from child;
+------+--------+-------------+-------------+
| code | name   | mother_code | father_code |
+------+--------+-------------+-------------+
| 001  | Jesus  | 001         | 002         |
| 002  | Cain   | 003         | 004         |
| 003  | Abel   | 003         | 004         |
| 004  | Set    | 003         | 004         |
| 005  | Samuel | 005         | 006         |
+------+--------+-------------+-------------+
5 rows in set (0.00 sec)

The goal is get the following: 目标是获得以下信息:

+------+--------+------+-------+-------------+-------------+
| code | name   | code | name  | mother_code | father_code |
+------+--------+------+-------+-------------+-------------+
| 001  | Mary   | 001  | Jesus | 001         | 002         |
| 002  | Joseph | 001  | Jesus | 001         | 002         |
+------+--------+------+-------+-------------+-------------+

I have tried the following: 我尝试了以下方法:

SELECT p.*, c.* FROM parent p,
                     child c,
                     (SELECT pm.code AS m_code FROM parent pm) AS m,
                     (SELECT pf.code AS f_code FROM parent pf) AS f
                WHERE
                     m.m_code='001' AND
                     f.f_code='002' AND
                     c.mother_code=m.m_code AND
                     c.father_code=f.f_code AND
                     c.mother_code='001' AND
                     c.father_code='002' AND
                     c.code='001';

The where clause would look redundant and it is because I am trying to get the desired result, thus it contains attempts to write correct the query. where子句看起来很多余,这是因为我试图获得所需的结果,因此它包含尝试编写正确的查询的尝试。

But always returns: 但总是返回:

+------+--------+------+-------+-------------+-------------+
| code | name   | code | name  | mother_code | father_code |
+------+--------+------+-------+-------------+-------------+
| 001  | Mary   | 001  | Jesus | 001         | 002         |
| 002  | Joseph | 001  | Jesus | 001         | 002         |
| 003  | Adan   | 001  | Jesus | 001         | 002         |
| 004  | Eva    | 001  | Jesus | 001         | 002         |
| 005  | Ana    | 001  | Jesus | 001         | 002         |
| 006  | Elcana | 001  | Jesus | 001         | 002         |
+------+--------+------+-------+-------------+-------------+
6 rows in set (0.00 sec)

Thus what is the correct sentence? 那么正确的句子是什么?

Are you just looking for two join s? 您是否正在寻找两个join

select c.*, pm.name as mother_name, pf.name as father_name
from child c join
     parent pm
     on c.mother_code = pm.code join
     parent pf
     on c.father_code = pf.code;

You can add a where clause to filter this down to particular children: 您可以添加where子句以将其过滤到特定子项:

where c.code in ('001', '002')

From your expected result I think this is what you need: 从您的预期结果中,我认为这是您需要的:

select
  p.code, p.name,
  c.code, c.name,
  c.mother_code, c.father_code
from parent p 
inner join child c 
on c.mother_code = p.code or c.father_code = p.code 

You can add any condition you need with a WHERE clause. 您可以使用WHERE子句添加所需的任何条件。
See the demo . 参见演示
Results: 结果:

| code | name   | code | name   | mother_code | father_code |
| ---- | ------ | ---- | ------ | ----------- | ----------- |
| 001  | Mary   | 001  | Jesus  | 001         | 002         |
| 002  | Joseph | 001  | Jesus  | 001         | 002         |
| 003  | Adan   | 002  | Cain   | 003         | 004         |
| 004  | Eva    | 002  | Cain   | 003         | 004         |
| 003  | Adan   | 003  | Abel   | 003         | 004         |
| 004  | Eva    | 003  | Abel   | 003         | 004         |
| 003  | Adan   | 004  | Set    | 003         | 004         |
| 004  | Eva    | 004  | Set    | 003         | 004         |
| 005  | Ana    | 005  | Samuel | 005         | 006         |
| 006  | Elcana | 005  | Samuel | 005         | 006         |

If the dependency is on the child to get the parents, use or on your join. 如果依赖孩子来获得父母,请使用或加入。

SELECT p.Code, p.[Name], c.Code, p.[Name], c.Mother_Code, c.Father_Code
FROM Parent p JOIN Child c ON c.Mother_Code = p.Code OR c.Father_Code = p.Code
WHERE c.name = 'Jesus'

If the dependency is to find a parent's children, then just alter the WHERE statement 如果依赖关系是查找父母的孩子,则只需更改WHERE语句

SELECT p.Code, p.[Name], c.Code, p.[Name], c.Mother_Code, c.Father_Code
FROM Parent p JOIN Child c ON c.Mother_Code = p.Code OR c.Father_Code = p.Code
WHERE p.name IN ('Mary', 'Joseph')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM