ForeignKey引用相同的表

时间:2012-10-03 12:35:09

标签: mysql sql

有一个面试测试,下面是表和结构

 Table Person = id, name, dob, dod, mother_id, father_id
 Primary Key (id)
 Foreign Key mother_id references Person
 Foreign Key father_id references Person

有人问了

  
      
  1. “选择所有母亲”
  2.   
  3. “选择那些'John Smith'和'Jane'
  4. 的孩子   

我感到困惑,因为我假设外键会像往常一样与其他表连接。但那时我失败了。有人知道实际答案和原因吗?

5 个答案:

答案 0 :(得分:15)

这种数据结构称为“自引用表”

SELECT DISTINCT mothers.*
FROM person
    inner join person mothers on person.mother_id = mothers.id

SELECT person.*
FROM person
    inner join person fathers on person.father_id = fathers.id
    inner join person mothers on person.mother_id = mothers.id
WHERE 
    fathers.name='john smith'
and 
    mothers.name='jane'

答案 1 :(得分:2)

你总是可以拥有链接到同一个表的外键..那里没有问题..

请参阅,假设您将人员记录存储在表格中,现在该人员将拥有母亲和父亲。 motherfather两者本身就是一个人......所以,它们本身就是同一张桌子的记录......

假设您在Person表中有以下两条记录: -

id     name           age         mother_id
1      xyz            24          5
5      abc            57          6

因此,从上表中可以看出person id = 5 id = 1实际上是foreign key的人的母亲。所以,join引用了SELECT p2.id FROM Person p1 join Person p2 WHERE p1.mother_id = p2.id 表..

因此,这里不是使用不同的表执行mother操作,而是必须使用同一个表执行连接。

{{1}}

此查询将选择当前记录的{{1}}记录..

答案 2 :(得分:2)

  

我假设外键会与其他表链接   像往常一样。

它仍然是 - 它引用同一个Person表中的其他记录。

-- All Mothers
SELECT mom.name
   FROM Person mom
   WHERE EXISTS (SELECT 1 FROM Person WHERE mother_id = mom.id);

-- Children of John Smith and Jane
SELECT kid.name
   FROM Person kid
   INNER JOIN Person mom on kid.mother_id = mom.id
   INNER JOIN Person dad on kid.father_id = dad.id
   WHERE mom.name = 'Jane' AND
   dad.name = 'John Smith';

在这里查看SQL fiddle

答案 3 :(得分:1)

SELECT * 
FROM Person 
WHERE father_id = (SELECT id FROM Person WHERE name = 'John Smith')
AND    mother_id = (SELECT id FROM Person WHERE name = 'Jane')

答案 4 :(得分:1)

podiluska已经给出了答案,只是解释了它是如何工作的,因为看起来你是MySql的新手。

通过给表(就像母亲或父亲给表人)一样的别名,你做了类似伪表的事情,MySql解释为另一个表,所以连接正常发生,想象现在有3个表。人,父亲和母亲,他们都是通过加入联系在一起的。