0

I have this table structure:

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 ;

and the data:

(`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');

What I need is to gather the list of persons whose SPOUSE is also their FIRST-DEGREE COUSIN?

Can anyone help me with how to formulate the MySQL query?

4

2 回答 2

1

假设有孩子的人结婚了(没有孩子的人没有结婚)那么可能可以这样做。但可能效率不高。

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

有 2 个大子选择,每个选择一个人和他们的孙子,在 ID 字段上连接在一起,以便他们共享祖父母。然后将这些与persons表连接起来,将一个子选择视为父亲,一个作为母亲,以获取其父母共享祖父母的任何人,然后再次将其与person表连接以获取实际的父母。

编辑 - 更短的代码。

我已经减少了上述内容,因此通过在 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
于 2013-06-04T16:01:10.117 回答
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)
    )
于 2013-06-04T16:06:41.847 回答