在同一个 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
我有一个外键指向同一个 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