SQL从父列表中查找顶级父级

时间:2011-07-12 16:49:31

标签: sql

我有两个表:table 1有一列父ID(P-id),table 2有两列:P_id和C-id(子ID)。

在表2中,为每个孩子显示父母,但孩子可以有多于一个父母,反之亦然。(多对多)。现在我需要找到所有P-id,这些P-id表示在这个P-id | C_id关系中没有父母自己基于的父母。我认为困难在于没有关于父级的直接信息。

P_id
------
1
2
3

C_id
------
1 
2 
3 
4 
5

P_id   C_id
-----------
1      1  
1      2  
1      3   
2      1   
2      2   
2      3   
2      4   
3      1  
3      5  
3      3  

答案应该是P_id 2和3

2 个答案:

答案 0 :(得分:0)

SELECT p_id from TableA as A
WHERE NOT EXISTS (SELECT * FROM TableB as B
                  WHERE B.C_id = A.P_ID)

这将显示所有父母的ID在第二个表中没有显示为child_id。

修改

试试这个......

SELECT b1.p_id 
from #TableB as B1
WHERE c_id NOT IN ( SELECT c_id
                    FROM #TableB as b2
                    WHERE b2.p_id <> b1.p_id)

如果我正确地思考这个问题,这应该会显示所有parent_id,其中包含没有其他parent_id的child_id。

答案 1 :(得分:0)

我已经探讨过这个问题了。根据您的要求,您应该将关系表视为DAG。你需要提升,直到找到没有父母的行。

这本质上是一个递归操作,所以你的SQL版本将在这里发挥作用。

给定一个值,你可以找到父(或缺少),然后你需要重新运行相同的测试以确定相同的东西....一直到你找不到父。

您的情况是否会限制嵌套层的数量?如果是这样,这可以通过完成,而无需递归。

请在此处查看我的问题以进一步讨论:
Return all nodes in many-to-many hierarchal tree

编辑:
假设你有一个有限的嵌套深度为3,你可能只需JOIN反复来耗尽你的嵌套深度。

SELECT 
    *
FROM 
    table a
LEFT OUTER JOIN table b 
    ON b.C_id = a.P_id
LEFT OUTER JOIN table c 
    ON c.C_id = b.P_id
LEFT OUTER JOIN table d 
    ON d.C_id = c.P_id
WHERE
    a.C_id = @pYourValue
    AND (
        a.P_id IS NULL 
        OR b.P_id IS NULL
        OR c.P_id IS NULL
        OR d.P_id IS NULL
        )

只有拥有已知的有限嵌套深度

时,此方法才有效