获取谱系树中特定信息的第一次出现,然后停止

问题描述 投票:0回答:1

我有以下数据集,可以重新组装家谱树。

祖先 家长 级别 孩子 头发颜色
托尼 1 棕色 托尼
托尼 托尼 2 玛丽 棕色 托尼 - 玛丽
托尼 托尼 2 约翰 黑色 托尼 - 约翰
托尼 玛丽 3 凯蒂 棕色 托尼 - 玛丽 - 凯蒂
托尼 玛丽 3 杰夫 黑色 托尼 - 玛丽 - 杰夫
托尼 约翰 3 迈克 棕色 托尼 - 约翰 - 迈克
托尼 约翰 3 埃文 棕色 托尼 - 约翰 - 埃文
托尼 凯蒂 4 卢卡 棕色 托尼 - 玛丽 - 凯蒂 - 卢卡
托尼 凯蒂 4 伊斯拉 黑色 托尼 - 玛丽 - 杰夫 - 艾拉
托尼 埃文 4 芬恩 黑色 托尼 - 约翰 - 埃文 - 芬恩

我想从祖先托尼开始搜索每个家族,并返回第一个头发颜色为黑色的孩子。

  • 所以从托尼(第 1 级)开始,因为他没有头发,我会走进树。
  • 继续看他的孩子,玛丽和约翰(2级),我们可以看到玛丽的头发是棕色的,所以我们继续她的路线,但是约翰的头发是黑色所以我会停在那里,尽管他的芬恩也有头发。
  • 回到 Mary 的队伍,我们去找 Katy 和 Jeff(第 3 级)。正如我们所看到的,凯蒂的头发是棕色的,所以我们继续前进,但是杰夫的头发是黑色,所以我们停在那里。
  • 然后凯蒂的孩子卢卡有棕色头发,所以我们也停在那里。生成的数据集将如下所示(Finn 被排除,因为我们不再关注 John):
祖先 家长 级别 孩子 头发颜色
托尼 托尼 2 约翰 黑色 托尼 - 约翰
托尼 玛丽 3 杰夫 黑色 托尼 - 玛丽 - 杰夫
托尼 凯蒂 4 伊斯拉 黑色 托尼 - 玛丽 - 杰夫 - 艾拉

为了实现这一目标,我尝试使用 not inis like 来创建一个由祖先、父级和级别(对于 Black 头发颜色)组成的键,并将它们从数据集中排除,但它不起作用(我无法将两者合并在同一个子查询中)。

如果有任何其他想法来解决这个问题,我将不胜感激。

sql oracle
1个回答
0
投票

您可以使用分层查询:

SELECT parent,
       child,
       hair_color,
       SUBSTR(SYS_CONNECT_BY_PATH(child, ' - '), 4) AS tree
FROM   table_name
WHERE  hair_color = 'Black'
START WITH parent IS NULL
CONNECT BY
       PRIOR child = parent
AND    PRIOR hair_color <> 'Black';

对于样本数据:

CREATE TABLE table_name (parent, child, hair_color) AS
SELECT NULL,   'Tony', 'Brown' FROM DUAL UNION ALL
SELECT 'Tony', 'Mary', 'Brown' FROM DUAL UNION ALL
SELECT 'Tony', 'John', 'Black' FROM DUAL UNION ALL
SELECT 'Mary', 'Katy', 'Brown' FROM DUAL UNION ALL
SELECT 'Mary', 'Jeff', 'Black' FROM DUAL UNION ALL
SELECT 'John', 'Mike', 'Brown' FROM DUAL UNION ALL
SELECT 'John', 'Evan', 'Brown' FROM DUAL UNION ALL
SELECT 'Katy', 'Luca', 'Brown' FROM DUAL UNION ALL
SELECT 'Katy', 'Isla', 'Black' FROM DUAL UNION ALL
SELECT 'Evan', 'Finn', 'Black' FROM DUAL;

输出:

家长 孩子 头发颜色
托尼 约翰 黑色 托尼 - 约翰
玛丽 杰夫 黑色 托尼 - 玛丽 - 杰夫
凯蒂 伊斯拉 黑色 托尼 - 玛丽 - 凯蒂 - 艾拉

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.