如何创建一个递归计数器来查找一个元素有多少个父级和子级?

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

How to create a recursive counter to find out how many parents and children have an element?

问题

I have 2 tables.
Table with reletions and table with deals.
In my table of deals I have a list of DealID's and for them I have to find out how many parents or children they have

The scripts are here:
https://dbfiddle.uk/ZM9fuv7C

Ultimately I have to get this result

DealID ParentCNT ChildCNT
106 2 1
107 1 2
108 2 0
109 0 0
WITH rec4 (ParentID, ChildID)
AS 
(
    SELECT ParentID, ChildID
    FROM t_parent 
    UNION ALL
    SELECT p.ParentID, p.ChildID
    FROM t_parent AS p
        JOIN rec4 AS r ON p.ParentID = r.ChildID

), rec5 (ParentID, ChildID)
AS 
(
    SELECT ParentID, ChildID
    FROM t_parent 
    UNION ALL
    SELECT p.ParentID, p.ChildID
    FROM t_parent AS p
        JOIN rec5 AS r ON p.ChildID = r.ParentID
)
select ch.ParentID, ChildCNT, ParentCNT from (
select ParentID, COUNT(r5.ChildID) as ChildCNT from rec5 r5 Group by ParentID) ch
join (select ChildID, COUNT(r4.ParentID) as ParentCNT from rec4 r4 Group by ChildID) pr
on ch.ParentID = pr.ChildID;
英文:

I have 2 tables.
Table with reletions and table with deals.
In my table of deals I have a list of DealID's and for them I have to find out how many parents or children they have

The scripts are here:
https://dbfiddle.uk/ZM9fuv7C

Ultimately I have to get this result

DealID ParentCNT ChildCNT
106 2 1
107 1 2
108 2 0
109 0 0
WITH rec4 (ParentID, ChildID)
AS 
(
    SELECT ParentID, ChildID
    FROM t_parent 
 -- where ChildID = 106
    UNION ALL
    SELECT p.ParentID, p.ChildID
    FROM t_parent AS p
        JOIN rec4 AS r ON p.ParentID = r.ChildID

), rec5 (ParentID, ChildID)
AS 
(
    SELECT ParentID, ChildID
    FROM t_parent 
 -- where ChildID = 106
    UNION ALL
    SELECT p.ParentID, p.ChildID
    FROM t_parent AS p
        JOIN rec5 AS r ON p.ChildID = r.ParentID
)
--select ISNULL(a.DealID, 0), ttt.ParentCNT, ttt.ChildCNT
  --from #A a left join
  select ch.ParentID, ChildCNT, ParentCNT from (
select ParentID, COUNT(r5.ChildID) as ChildCNT from rec5 r5 Group by ParentID) ch
join (select ChildID, COUNT(r4.ParentID) as ParentCNT from rec4 r4 Group by ChildID) pr
on ch.ParentID = pr.ChildID--) ttt
--on a.DealID = ttt.ParentID```


</details>


# 答案1
**得分**: 1

使用两个不同的递归公共表达式(一个用于子项,另一个用于父项)似乎是一个相关的方法。然后我们可以将它们进行 `full join`,并进行聚合和计数:

```sql
with 
    children as (
        -- 省略部分代码
    ),
    parents as (
        -- 省略部分代码
    )
select coalesce(c.dealid, p.dealid) as dealid,
    count(distinct p.parentid) as parent_cnt,
    count(distinct c.childid)  as child_cnt
from children c
full join parents p on p.dealid = c.dealid
group by coalesce(c.dealid, p.dealid)
英文:

Using two distinct recursive CTEs (one for the children, and the other for the parents) looks like a relevant approach.. Then we can full join them, aggregate and count:

with 
    children as (
        select parentid as dealid, parentid, childid from t_parent
        union all
        select r.dealid, p.parentid, p.childid
        from children r
        inner join t_parent p on p.parentid = r.childid
    ),
    parents as (
        select childid as dealid, parentid, childid from t_parent
        union all
        select r.dealid, p.parentid, p.childid
        from parents r
        inner join t_parent p on p.childid = r.parentid
    )
select coalesce(c.dealid, p.dealid) as dealid,
    count(distinct p.parentid) as parent_cnt,
    count(distinct c.childid)  as child_cnt
from children c
full join parents p on p.dealid = c.dealid
group by coalesce(c.dealid, p.dealid)
dealid parent_cnt child_cnt
101 0 3
102 0 2
103 1 2
104 0 3
105 1 1
106 2 1
107 1 2
108 2 0
110 3 0
111 2 1
112 3 0

fiddle

I am not sure which logic you want to filter out records in the final resultset ; you might want to add a where clause to the outer select.

huangapple
  • 本文由 发表于 2023年6月15日 14:39:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76479754.html
匿名

发表评论

匿名网友

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

确定