我有一个公司表,有三列:holder_co_id,held_co_id,pct_owned。
holder_co_id held_co_id pct_owned
A B 25
A C 50
B C 50
C B 10
所以我的查询确定A持有25%的B,A持有50%的C,而A持有另外5%的B通过它持有50%的C和另外12.5%的C通过抱着B。
我对自己非常满意,因为我曾经钉过一些sql。这并没有持续多久。我注意到,通过B和C的共同所有权,这会将查询发送到无限循环中。我已经尝试通过在循环上放置一个最大值来停止循环,但是在某些情况下这会使所有权仍然高于100%...此外,它只是不正确。
除了:
之外我还会怎么做呢?WITH Result AS
(SELECT HOLDER_CO_ID,
HELD_CO_ID,
PCT_OWNED,
1 AS generationsremoved
FROM dbo.ALL_HOLDING_INFO
UNION ALL
SELECT P.HOLDER_CO_ID,
N.HELD_CO_ID,
P.PCT_OWNED * N.PCT_OWNED AS Expr1,
P.generationsremoved + 1 AS Expr2
FROM Result AS P INNER JOIN
dbo.ALL_HOLDING_INFO AS N ON P.HELD_CO_ID = N.HOLDER_CO_ID
WHERE (P.generationsremoved <= 10))
SELECT DISTINCT TOP (100) PERCENT HOLDER_CO_ID,
HELD_CO_ID,
PCT_OWNED,
generationsremoved
FROM Result AS Result_1
WHERE (PCT_OWNED > 0.005)
ORDER BY HOLDER_CO_ID, HELD_CO_ID, generationsremoved DESC
答案 0 :(得分:2)
尝试停止CTE iteration
上的Recursive block
,而不是在外面执行此操作,我的猜测是,如果您在SQL尝试构建它(在递归块内)时停止它,它将无法获得进入一个无限循环
WITH Result AS
(SELECT HOLDER_CO_ID,
HELD_CO_ID,
PCT_OWNED,
1 AS generationsremoved
FROM dbo.ALL_HOLDING_INFO
UNION ALL
SELECT P.HOLDER_CO_ID,
N.HELD_CO_ID,
P.PCT_OWNED * N.PCT_OWNED AS Expr1,
P.generationsremoved + 1 AS Expr2
FROM Result AS P INNER JOIN
dbo.ALL_HOLDING_INFO AS N ON P.HELD_CO_ID = N.HOLDER_CO_ID
WHERE (P.generationsremoved<= 10)
AND (PCT_OWNED > 0.005))
SELECT DISTINCT TOP (100) PERCENT HOLDER_CO_ID,
HELD_CO_ID,
PCT_OWNED,
generationsremoved
FROM Result AS Result_1
答案 1 :(得分:1)
这会给你你想要的。它首先创建一个层次结构然后遍历它,最后总结聚合以获得总持有量。只要HOLDER_CO_ID或HELD_CO_ID都没有|
,这就行了......
/*
If Object_ID('dbo.ALL_HOLDING_INFO') Is Not Null Drop Table dbo.ALL_HOLDING_INFO
Create Table dbo.ALL_HOLDING_INFO (HOLDER_CO_ID Varchar(10), HELD_CO_ID Varchar(10), PCT_OWNED Float)
Insert dbo.ALL_HOLDING_INFO
Values ('A', 'B', .25),('A', 'C', .50),('B' ,'C', .50),('C','B',.10);
*/
With Hierarchy As
(
Select Distinct HOLDER_CO_ID As HOLDER_CO_ID,
HELD_CO_ID As HELD_CO_ID,
PCT_OWNED,
Convert(Varchar(Max),'|' + HELD_CO_ID + '|') As AllChildren,
0 As RelationDepth
From dbo.ALL_HOLDING_INFO
Union All
Select h.HOLDER_CO_ID,
a.HELD_CO_ID As HELD_CO_ID,
a.PCT_OWNED,
Convert(Varchar(Max),h.AllChildren + a.HELD_CO_ID) + '|' As AllChildren,
h.RelationDepth + 1
From Hierarchy h
Join dbo.ALL_HOLDING_INFO a
On h.HELD_CO_ID = a.HOLDER_CO_ID
Where h.HOLDER_CO_ID != a.HELD_CO_ID
And h.AllChildren Not Like '%|' + a.HELD_CO_ID + '|%'
), Result AS
(
SELECT Row_Number() Over (Order By Holder_CO_ID, PCT_OWNED) As tID,
HOLDER_CO_ID,
HELD_CO_ID,
PCT_OWNED,
RelationDepth
FROM Hierarchy
Where RelationDepth = 0
UNION ALL
SELECT p.tID,
P.HOLDER_CO_ID,
N.HELD_CO_ID,
P.PCT_OWNED * N.PCT_OWNED AS Expr1,
n.RelationDepth
FROM Result AS P
JOIN Hierarchy AS N
ON P.HOLDER_CO_ID = N.HOLDER_CO_ID
And p.HELD_CO_ID != n.HELD_CO_ID
And p.RelationDepth = n.RelationDepth - 1
)
SELECT HOLDER_CO_ID, HELD_CO_ID, SUM(PCT_OWNED)*100 As PCT_OWNED
FROM Result AS Result_1
Group By HOLDER_CO_ID, HELD_CO_ID
ORDER BY HOLDER_CO_ID, HELD_CO_ID DESC