我有两列的表
----------------------
| 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');
我在这里有示例数据,如图所示。
所需的输出将是
所以我试图用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
但是无法获得理想的结果。因此寻找解决方案。
答案 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