如何使用SQL查找祖父母?

时间:2019-06-25 15:58:52

标签: sql netezza

我有两列的表

 ----------------------
|  NAME | FATHER_NAME  |
 ----------------------
DDL :

CREATE TABLE RELATION (NAME VARCHAR(20), FATHER_NAME VARCHAR(20));

INSERT INTO RELATION VALUES ('ADESH','ASHOK');
INSERT INTO RELATION VALUES ('ASHOK','KA');
INSERT INTO RELATION VALUES ('KA',NULL);
INSERT INTO RELATION VALUES ('ANSH','ADESH');
INSERT INTO RELATION VALUES ('BASH','ANSH');

INSERT INTO RELATION VALUES ('DEVEN','SUBASH');
INSERT INTO RELATION VALUES ('SUBASH','KA');

INSERT INTO RELATION VALUES ('PRAKASH',NULL);
INSERT INTO RELATION VALUES ('PRADEEP','PRAKASH');
INSERT INTO RELATION VALUES ('SAI','PRADEEP');

我在这里有示例数据,如图所示。

enter image description here

所需的输出将是

enter image description here

所以我试图用CONNECT_BY或递归CTE来解决这个问题

WITH REL_CTE AS
(
    SELECT NAME,FATHER_NAME, 1 AS L
    FROM RELATION 
    WHERE FATHER_NAME IS NULL

    UNION ALL

    SELECT R.NAME,R.FATHER_NAME,CTE.L+1
    FROM RELATION R JOIN REL_CTE CTE
    ON R.FATHER_NAME = CTE.NAME

)

SELECT * FROM REL_CTE 

但是无法获得理想的结果。因此寻找解决方案。

1 个答案:

答案 0 :(得分:0)

实现此目的的一种可能方法是使用递归CTE,如下所示。但是,如果您始终想要完全的祖父母,即我->父亲->祖父,则可以进行自我加入,这比CTE的效率要高得多。请注意,有了CTE,您可以得到曾祖父母等...

自我加入

select distinct
    L2.FATHER_NAME as GRANDFATHER_NAME
from
    dbo.RELATION as L1
inner join
    dbo.RELATION as L2
    on
        L1.FATHER_NAME = L2.[NAME]
where
    L2.FATHER_NAME is not null

递归CTE

WITH REL_CTE AS
(
-- the initial result will be every record from the relation
-- table with level 1
select NAME,FATHER_NAME, 1 as L
from RELATION

-- now start recursively walking up the tree
union all
select
      cte.NAME
    , rel.FATHER_NAME -- this will be the father at the coresponding level
                      -- so when L = 1 Father, L = 2 Grandfather, L = 3 Great Grandfather
    , cte.L+1 as L
from
    REL_CTE as cte
inner join
    dbo.RELATION as rel
    on
        cte.FATHER_NAME = rel.NAME

)
-- if you specifically want grandparents you would only
-- want things at level 2
select distinct REL_CTE.FATHER_NAME from REL_CTE
where L = 2 and REL_CTE.FATHER_NAME is not null