英文:
How to find grandparent parent child relationship for View in SQL
问题
以下是您要翻译的内容:
With a table that looks like this:
| ParentID | AgencyID | CompanyName | 
|---|---|---|
| NULL | 1 | ABC Agency | 
| NULL | 2 | Another Agency | 
| 2 | 3 | Agency 3 | 
| 3 | 4 | Agency 4 | 
The goal here is to develop a database view that shows the parent and grand-parent for a given agency. Some agencies only have a parent (no grand-parent), and still others are stand-alone - they don't have a parent. We want the view to look like this:
- GrandParentAgencyNo
- GrandParentName
- ParentAgencyNo
- ParentName 
- AgencyNo 
- AgencyName
- NumberOfChildren
- NumberOfGrandChildren
We could use that to find all the children for a given agency:
    select * from AgencyView where ParentAgencyNo = "ABC123";
if an agency doesn't have a parent, the above result should look like this:
- GrandParentAgencyNo: 1 
- GrandParentName: ABC Agency 
- ParentAgencyNo: 1
- ParentName: ABC Agency 
- AgencyNo: 1
- AgencyName: ABC Agency 
- NumberOfChildren: 0
- NumberOfGrandChildren: 0
I tried writing recursive functions similar to the one below (including other queries that included trying to find the grandparent) with no luck. I am unfamiliar with recursion and always seem to hit the max recursion rate in SQL Server.
with A(Id, ParentId) as 
(
    select AgencyId, ParentAgencyId from Agency 
    union all
    select e.AgencyId, p.ParentId from Agency e 
    join A p on e.ParentAgencyId = p.Id
)
select * from A
OPTION (MAXRECURSION 32767)
英文:
With a table that looks like this:
| ParentID | AgencyID | CompanyName | 
|---|---|---|
| NULL | 1 | ABC Agency | 
| NULL | 2 | Another Agency | 
| 2 | 3 | Agency 3 | 
| 3 | 4 | Agency 4 | 
The goal here is to develop a database view that shows the parent and grand-parent for a given agency. Some agencies only have a parent (no grand-parent), and still others are stand-alone - they don't have a parent. We want the view to look like this:
- GrandParentAgencyNo
- GrandParentName
- ParentAgencyNo
- ParentName 
- AgencyNo 
- AgencyName
- NumberOfChildren
- NumberOfGrandChildren
We could use that to find all the children for a given agency:
    select * from AgencyView where ParentAgencyNo = "ABC123"
if an agency doesn't have a parent, the above result should look like this:
- GrandParentAgencyNo: 1 
- GrandParentName: ABC Agency 
- ParentAgencyNo: 1
- ParentName: ABC Agency 
- AgencyNo: 1
- AgencyName: ABC Agency 
- NumberOfChildren: 0
- NumberOfGrandChildren: 0
I tried writing recursive functions similar to the one below (including other queries that included trying to find the grandparent) with no luck. I am unfamiliar with recursion and always seem to hit the max recursion rate in SQL Server.
with A(Id, ParentId) as 
(
    select AgencyId, ParentAgencyId from Agency 
    union all
    select e.AgencyId, p.ParentId from Agency e 
    join A p on e.ParentAgencyId = p.Id
)
select * from A
OPTION (MAXRECURSION 32767)
答案1
得分: 1
我不使用递归,除非必要,通常是因为存在未知或大量级别。我会简单地使用左连接和案例语句来获取父代和祖父代,以及用于子代计数的子查询。
SELECT A.Agencyid, A.CompanyName
, CASE WHEN p.AgencyId is not null then p.AgencyId 
       else A.AgencyID END AS ParentAgencyId
, CASE WHEN p.AgencyId is not null then p.CompanyName
       else A.CompanyName END AS ParentCompanyName
, CASE WHEN gp.AgencyId is not null then gp.AgencyId 
       WHEN p.AgencyId is not null then p.AgencyId 
       else A.AgencyID END AS GrandParentAgencyId
, CASE WHEN gp.AgencyId is not null then gp.CompanyName
       WHEN p.AgencyId is not null then p.CompanyName
       else A.CompanyName END AS GrandParentCompanyName
, (SELECT count(*) FROM Agency where ParentId = A.AgencyId) AS Children
, (SELECT count(*) FROM Agency C 
       JOIN Agency GC ON C.AgencyId = GC.ParentId 
       where C.ParentId = A.AgencyId) AS GrandChildren
FROM Agency A
LEFT JOIN Agency P ON P.AgencyId = A.ParentId
LEFT JOIN Agency GP ON GP.AgencyId = P.ParentId
WHERE A.AgencyId = 1
这是你提供的SQL查询的翻译部分。
英文:
I don't use recursion unless I have to, usually due to an unknown or large number of levels. I would simply use left joins and case statements to get parents and grandparents and a sub-select for the child counts.
SELECT A.Agencyid, A.CompanyName
, CASE WHEN p.AgencyId is not null then p.AgencyId 
       else A.AgencyID END AS ParentAgencyId
, CASE WHEN p.AgencyId is not null then p.CompanyName
       else A.CompanyNameEND ParentCompanyName
, CASE WHEN gp.AgencyId is not null then gp.AgencyId 
       WHEN p.AgencyId is not null then p.AgencyId 
       else A.AgencyID END GrandParentAgencyId
, CASE WHEN gp.AgencyId is not null then gp.CompanyName
       WHEN p.AgencyId is not null then p.CompanyName
       else A.CompanyNameEND GrandParentCompanyName
, (SELECT count(*) FROM Agency where ParentId = A.AgencyId) Children
, (SELECT count(*) FROM Agency C 
       JOIN Agency GC ON C.AgencyId = GC.ParentId 
       where C.ParentId = A.AgencyId) GrandChildren
FROM Agency A
LEFT JOIN Agency P ON P.AgencyId = A.ParentId
LEFT JOIN Agency GP ON GP.AgencyId = P.ParentId
WHERE A.AgencyId = 1
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论