我有这个表结构:
CREATE TABLE IF NOT EXISTS `person` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`father` text NOT NULL,
`mother` text NOT NULL,
`name` text NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=16 ;
和数据:
(`ID`, `father`, `mother`, `name`)
( 1 '' '' 'Robert Darwin'),
( 2 '' '' 'Josiah Wedgwood'),
( 3 '' '' 'Sarah Wedgwood'),
( 4 '' '' 'Mary Howard'),
( 5 1 '' 'Erasmus Darwin'),
( 6 '' '' 'Elizabeth Allen'),
( 7 2 3 'Josiah II'),
( 8 2 3 'Susannah Wedgwood'),
( 9 5 4 'Robert Waring Darwin'),
( 10 7 6 'Josiah III'),
( 11 7 6 'Emma Wedgwood'),
( 12 9 8 'Charles Robert'),
( 13 9 8 'Caroline Sarah Darwin'),
( 14 10 13 'Margaret Wedgwood'),
( 15 11 12 'William Erasmus');
我需要的是收集 SPOUSE 也是 FIRST-DEGREE COUSIN 的人员名单?
任何人都可以帮我解决如何制定MySQL查询的问题吗?
答案 0 :(得分:0)
假设有孩子的人已经结婚(没有孩子的人没有结婚)那么可能就这样做了。但可能效率不高。
SELECT DISTINCT f.name
FROM (
SELECT a.ID AS Parent, c.ID AS GrandChild
FROM person a
INNER JOIN person b ON a.ID = b.father
INNER JOIN person c ON b.ID = c.father
UNION
SELECT a.ID, c.ID
FROM person a
INNER JOIN person b ON a.ID = b.father
INNER JOIN person c ON b.ID = c.mother
UNION
SELECT a.ID, c.ID
FROM person a
INNER JOIN person b ON a.ID = b.mother
INNER JOIN person c ON b.ID = c.mother
UNION
SELECT a.ID, c.ID
FROM person a
INNER JOIN person b ON a.ID = b.mother
INNER JOIN person c ON b.ID = c.father) y
INNER JOIN (
SELECT a.ID AS Parent, c.ID AS GrandChild
FROM person a
INNER JOIN person b ON a.ID = b.father
INNER JOIN person c ON b.ID = c.father
UNION
SELECT a.ID, c.ID
FROM person a
INNER JOIN person b ON a.ID = b.father
INNER JOIN person c ON b.ID = c.mother
UNION
SELECT a.ID, c.ID
FROM person a
INNER JOIN person b ON a.ID = b.mother
INNER JOIN person c ON b.ID = c.mother
UNION
SELECT a.ID, c.ID
FROM person a
INNER JOIN person b ON a.ID = b.mother
INNER JOIN person c ON b.ID = c.father) x
ON y.Parent = x.Parent
INNER JOIN person z ON z.father = x.GrandChild AND z.mother = y.GrandChild
INNER JOIN person f ON f.ID = z.father OR f.ID = z.mother
有两个大的子选择,每个选择一个人和他们的大孩子,在ID字段上连接在一起,所以他们共享祖父母。然后将这些与人员表联系起来,将一个子选择作为父亲,一个作为母亲,以使任何父母与父母共享的人,然后再次与人员表联系以获得实际的父母。
编辑 - 更短的代码。
我已经减少了上述内容,因此在JOIN的ON子句中使用OR来避免使用UNIONS。我倾向于讨厌在JOIN中使用OR,但它确实使它更具可读性。
SELECT DISTINCT f.name
FROM (
SELECT a.ID AS Parent, c.ID AS GrandChild
FROM person a
INNER JOIN person b ON a.ID = b.father OR a.ID = b.mother
INNER JOIN person c ON b.ID = c.father OR b.ID = c.mother
) y
INNER JOIN (
SELECT a.ID AS Parent, c.ID AS GrandChild
FROM person a
INNER JOIN person b ON a.ID = b.father OR a.ID = b.mother
INNER JOIN person c ON b.ID = c.father OR b.ID = c.mother
) x
ON y.Parent = x.Parent
INNER JOIN person z ON z.father = x.GrandChild AND z.mother = y.GrandChild
INNER JOIN person f ON f.ID = z.father OR f.ID = z.mother
答案 1 :(得分:0)
即使这个问题听起来像家庭作业,但我不是一个评判的人。我这样做是为了锻炼我的想法:
SELECT p1.father, p1.mother
FROM person p1
WHERE
(p1.father, p1.mother) IN (
SELECT firstSiblingChild.ID AS ID1, secondSiblingChild.ID AS ID2
FROM (
SELECT p1.ID AS ID1, p2.ID AS ID2
FROM person p1
INNER JOIN person p2 ON (p1.father = p2.father AND p1.mother = p2.mother)
WHERE
p1.father <> ""
AND
p1.mother <> ""
AND
p1.ID <> p2.ID
) siblings
INNER JOIN person firstSiblingChild ON (siblings.ID1 = firstSiblingChild.father OR siblings.ID1 = firstSiblingChild.mother)
INNER JOIN person secondSiblingChild ON (siblings.ID2 = secondSiblingChild.father OR siblings.ID2 = secondSiblingChild.mother)
)