如何在SQL中查找视图的祖父父母子关系

huangapple go评论55阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年2月9日 01:19:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75389445.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定