用于检查两个人是否有共同祖先的sql函数

时间:2013-10-20 17:16:04

标签: sql oracle

我必须解决以下问题:创建一个sql函数,检查两个人是否有共同的祖先,但我被卡住了。 我创建了

create type person as object
(
first_name varchar2(10),
last_namevarchar2(10)
);

和人员表

create table client_iulia
(Person_Id varchar2(13)constraint pk_id_client primary key,
Mother_Id varchar2(13),
Father_Id varchar2(13),
Name person);

我想要做的是一个具有三个参数(两个人和搜索级别)的函数,如果有共同的祖先则返回1,否则返回0) 如果有人有任何想法,请帮助我。 抱歉我的英语很差。

2 个答案:

答案 0 :(得分:3)

递归CTE是要走的路。我认为这是最容易理解的。可能有更快的方法,但应该清楚它是如何工作的。我无法访问oracle服务器,所以我可能有拼写错误,我在下面显示两个步骤,以便您可以测试并了解它是如何工作的。

1)查找单个输入的所有祖先

with ancestors as
(
   SELECT *
   FROM client_iulia 
   WHERE Person_Id = @inputPerson
     UNION ALL
   SELECT *
   FROM client_iulia
   JOIN ancestors a on Person_ID = a.Mother_ID OR Person_ID = a.Father_ID
)
SELECT * 
FROM ancestors

2)查找两个目标的所有祖先

with ancestorsA as
(
   SELECT *
   FROM client_iulia 
   WHERE Person_Id = @inputPersonA
     UNION ALL
   SELECT *
   FROM client_iulia
   JOIN ancestorsA a on Person_ID = a.Mother_ID OR Person_ID = a.Father_ID
), ancestorsB as
(
   SELECT *
   FROM client_iulia 
   WHERE Person_Id = @inputPersonB
     UNION ALL
   SELECT *
   FROM client_iulia
   JOIN ancestorsB a on Person_ID = a.Mother_ID OR Person_ID = a.Father_ID
)
SELECT A.* 
FROM ancestorsA A
JOIN ancestorsB B ON A.Person_Id = B.Person_Id

答案 1 :(得分:0)

哇,这太棘手了。您需要递归查询才能获得任何一个人的所有祖先。因为有两个父母,你会得到一对母亲和父亲,然而,你需要分成单个祖先。然后看看这些集合是否至少有一个共同的祖先。当至少有一个共同的祖先时,此语句给出1,否则为0:

    with ancestors_of_person_1 as
    (
      select mother_id, father_id
      from client_iulia
      start with person_id = 1
      connect by person_id = prior mother_id or person_id = prior father_id
    )
    , ancestors_of_person_2 as
    (
      select mother_id, father_id
      from client_iulia
      start with person_id = 2
      connect by person_id = prior mother_id or person_id = prior father_id
    )
    select count(*)
    from
    (
      (
      select mother_id as ancestor from ancestors_of_person_1 
      union 
      select father_id as ancestor from ancestors_of_person_1
      )
      intersect
      (
      select mother_id as ancestor from ancestors_of_person_2 
      union 
      select father_id as ancestor from ancestors_of_person_2
      )
    )
    where rownum = 1;
编辑:这是一个sqlfiddle。第1和第3人具有共同的祖先122,而第1和第2人没有共同之处。试一试:sqlfiddle