【问题标题】:sql function for checking if two persons have common ancestors用于检查两个人是否有共同祖先的sql函数
【发布时间】:2013-10-20 17:16:04
【问题描述】:

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

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

和 Persons 表

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) 请,如果有人有任何想法,请帮助我。 对不起我的英语不好。

【问题讨论】:

  • 您已标记 SQL Server,但 varchar2 是 Oracle。

标签: sql oracle


【解决方案1】:

递归 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

【讨论】:

  • 非常感谢。真的帮助我了解如何解决问题
  • @JohnFlores - 我刚刚修正了一个错字。
【解决方案2】:

哇,这很棘手。您需要递归查询来获取任一人的所有祖先。由于有两个父母,您将获得一对父母,但是您需要将其拆分为单一祖先。然后看看这些集合是否至少有一个共同的祖先。当至少有一个共同祖先时,此语句为您提供 1,否则为 0:

与祖先_of_person_1 作为 ( 选择mother_id,father_id 来自client_iulia 从 person_id = 1 开始 通过 person_id = 先前的母亲 ID 或 person_id = 先前的父亲 ID 连接 ) ,祖先_of_person_2 为 ( 选择mother_id,father_id 来自client_iulia 从 person_id = 2 开始 通过 person_id = 先前的母亲 ID 或 person_id = 先前的父亲 ID 连接 ) 选择计数(*) 从 ( ( 从ancestors_of_person_1 中选择mother_id 作为祖先 联盟 从ancestors_of_person_1 中选择father_id 作为祖先 ) 相交 ( 从ancestors_of_person_2 中选择mother_id 作为祖先 联盟 从ancestors_of_person_2 中选择father_id 作为祖先 ) ) 其中rownum = 1;

编辑:这是一个 sqlfiddle。第 1 个人和第 3 个人有共同的祖先 122,而第 1 个人和第 2 个人没有共同祖先。试试看:sqlfiddle

【讨论】:

  • 我尝试了这个选项,但我收到 person_id=1 错误,它要求用分号终止前一个语句。我阅读了有关此错误的更多信息,但我不知道如何修复它。这是因为开始选择的字段必须在选定的字段中?非常感谢
  • 嗨,约翰,对不起,我混淆了表名。也许这导致了错误。我已经更正了我的答案并添加了一个 sqlfiddle 供您尝试。
  • 是的,这是我的错误。我想在 sql server 中编写此函数,但我编写了在 sql 中创建表的说明。我习惯使用 SQL 并且您编写的所有代码都可以工作,但我有并且我尝试让它在 SQL Server 中工作。谢谢!
  • 我明白了。 SQL Server 以不同的方式执行此操作。查找:SQL Server 中的分层查询。
猜你喜欢
  • 1970-01-01
  • 2013-06-09
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 2013-06-30
  • 1970-01-01
  • 2014-03-19
相关资源
最近更新 更多