在同一个 table 上加入外键并显示 parent 和 child

Join foreign key on the same table and show parent and child

我有一个外键指向同一个 table (child - parent) 的主键。

我正在尝试编写一个查询,它将以如下所示的形式显示结果:

Parent 1 
Parent 1 > Child 1
Parent 1 > Child 2
Parent 2 
Parent 2 > Child 2 
Parent 3 
Parent 4

我想离开加入table,尽管我很接近它,但我一直没能做到。让我知道我做错了什么,或者是否有更简单的解决方案。

SELECT 
    a.OrganizationTypeID,
    b.ParentOrganizationTypeID,
    a.Name ParentName,
    b.Name ChildName,
    CASE
        WHEN b.ParentOrganizationTypeID IS NULL THEN a.Name
        ELSE CONCAT_WS('>', a.Name, b.Name)
    END AS res
FROM
    tblOrganizationTypes a
        left JOIN
    tblOrganizationTypes b ON b.ParentOrganizationTypeID = a.OrganizationTypeID
WHERE a.DateDeleted is null
GROUP BY b.OrganizationTypeID
ORDER BY a.OrganizationTypeID , b.ParentOrganizationTypeID

请从您的查询中删除 Group by 子句。

SELECT 
    a.OrganizationTypeID,
    b.OrganizationTypeID,
    
    a.Name ParentName,
    b.Name ChildName,
    CASE
        WHEN b.ParentOrganizationTypeID IS NULL THEN a.Name
        ELSE CONCAT_WS('>', a.Name, b.Name)
    END AS res
FROM
    tblOrganizationTypes a
    left join    
    tblOrganizationTypes b on a.OrganizationTypeID=b.ParentOrganizationTypeID 
    or (a.ParentOrganizationTypeID is null and a.OrganizationTypeID=b.OrganizationTypeID)
where a.DateDeleted is null and b.Name is not null
ORDER BY a.ParentOrganizationTypeID , b.OrganizationTypeID

DB-Fiddle:

架构和插入语句:

 create table tblOrganizationTypes (OrganizationTypeID int, ParentOrganizationTypeID int, Name varchar(100),DateDeleted date);
 insert into tblOrganizationTypes values(1,null, 'parent',null);
 insert into tblOrganizationTypes values(2,1, 'child 1',null);
 insert into tblOrganizationTypes values(3,1, 'child 2',null);
 insert into tblOrganizationTypes values(5,null, 'parent 5',null);

查询:

 SELECT 
     a.OrganizationTypeID,
     b.OrganizationTypeID,
     
     a.Name ParentName,
     b.Name ChildName,
     CASE
         WHEN b.ParentOrganizationTypeID IS NULL THEN a.Name
         ELSE CONCAT_WS('>', a.Name, b.Name)
     END AS res
 FROM
     tblOrganizationTypes a
     left join    
     tblOrganizationTypes b on a.OrganizationTypeID=b.ParentOrganizationTypeID 
     or (a.ParentOrganizationTypeID is null and a.OrganizationTypeID=b.OrganizationTypeID)
 where a.DateDeleted is null and b.Name is not null
 ORDER BY a.ParentOrganizationTypeID , b.OrganizationTypeID

输出:

OrganizationTypeID OrganizationTypeID ParentName ChildName res
1 1 parent parent parent
1 2 parent child 1 parent>child 1
1 3 parent child 2 parent>child 2
5 5 parent 5 parent 5 parent 5

db<>fiddle here

我建议你把这两种情况分开:

-- roots
select a.OrganizationTypeID
    , a.ParentOrganizationTypeID
    , a.Name
    , a.Name as childname
    , a.Name as res
from tblOrganizationTypes a
where a.ParentOrganizationTypeID is null
  and a.DateDeleted is null 
union all
-- children of roots
SELECT 
    a.OrganizationTypeID,
    b.OrganizationTypeID,
    a.Name ParentName,
    b.Name ChildName,
    CONCAT_WS('>', a.Name, b.Name) AS res
FROM tblOrganizationTypes a
JOIN tblOrganizationTypes b 
    ON b.ParentOrganizationTypeID = a.OrganizationTypeID 
where a.DateDeleted is null 
ORDER BY OrganizationTypeID, ParentOrganizationTypeID;

如果你想要更深的嵌套,你可以轻松地将其转换为递归 CTE

我修改了你的Fiddle