0

내 계층 구조 데이터를 평가하는 데 문제가 있으며 매우 유용한 정보가 있습니다. value 그냥 숫자 통화의 가치 (일부 행이 자신의 값으로 NULL이됩니다) 그리고 마지막으로 operator이다, parentID 계층 구조를 생성하고 각각의 자녀에 대해 하나의 부모가, ID 자체의 설명입니다 :SQL Server 2012 함수를 사용하여 계층 구조에 값 추가/빼기

내 표 4 열이 3 비트 값 0, 1 and NULL이 될 수있는 비트입니다 (나중에 -, + and ignore에 대응하고 싶습니다). 운영자는 자녀가 부모와 관련된 연산자를 직접 공개합니다.

예. ID = 2

와 부모의 값을 계산하려고 내 기능의 목적은 재귀 적으로 모든 아이들과 경우 확인하여 주어진 IDvalue을 계산하는 것입니다 때 ID, ParentID, Operator, Value23, 2, 1, 2.22 운영자 (1)을 가지고 있으며, 따라서 추가된다 operator1입니다.을 추가하거나 0에서 뺍니다 (값이 무시되는 경우 NULL 인 경우).

은 지금까지 나는 주어진 ID의 모든 어린이와 하위 아이들이 하나 개의 테이블에 함께 수집 한 다음 case을 적용한 후 합계를 취 발견 재귀 CTE와 함수를 작성했다.

function [dbo].[total](
@id int) 
returns NUMERIC(20,2) 
AS 
BEGIN 
declare @total numeric(20,2); 

cte as(
SELECT id, parentid, operator, value, 0 as level 
    FROM data 
    WHERE pos = @pos 
    union all 
select t.id, t.parentid, t.operator, t.value, c.level + 1 
FROM 
    data t 
inner join cte c on c.id = t.parentid) 

SELECT @total = (select sum (case when operator = 0 then (5 * value) when operator = 1 then value/100 else 0 end) from cte); 
RETURN @total 
END 

이 기능은 일부 기능을 확장합니다. dbo.total(1)은이 예제에서 1 -2.5+3.5의 정확한 결과를 제공합니다.

ID  Operator Value ParentID 
1  1   NULL - 
2  1   NULL 1 
    3  0   2.5  2 
    4  1   3.5  2 

그러나 다른 경우에는 제대로 작동하지 않습니다. 이 예제에서는 34 (2)의 부모가 0 인 연산자를 "인식"하여 값을 빼서 다른 계산을 수행해야한다고 가정해도이 값은 5 + 2.5 + 2.5 = 10입니다. 5 - (2.5 + 2.5) = 0

나는이 문제에 직면 한 첫 번째 사람이 아니기를 희망하며이 주제에 관한 모든 대답을 기다리고 있습니다. 질문이 있으시면 언제든지 물어보십시오. :) 고마워요!

+0

유는 받았어 : 난 그냥 내가 가장 오래된 (최대 수준으로 분 레벨)

이 지금 어떻게 작동에 "막내"아이로부터 내 방식으로 작동 할 수 있도록 WHILE 루프를 추가 결과? @kacase –

+0

아직 아직 그것에 대해 노력하고 있습니다. @SarathAvanavu – kacase

+0

@SarathAvanavu 이제 알았습니다. – kacase

답변

0

이 문제를 해결하는 방법을 마침내 발견했습니다. 나는 여전히 동일한 CTE를 사용하고 있습니다.

function [dbo].[total](@id int) 
returns NUMERIC(20,2) 
AS 
BEGIN 
declare @total numeric(20,2); 
declare @level int; 
declare @cte table (id int, parentid int,operator bit,value numeric(20,2),level int); 

--the same cte that i had used earlier 
cte as 
(SELECT id, parentid, operator, value, 0 as level 
    FROM 
    data 
    WHERE id = @id 
union all 
select t.id, t.parentid, t.operator, t.value, c.level + 1 
FROM 
    data t 
inner join cte c on c.id = t.parentid 
) 

--write the calculated cte to @cte 
insert into @cte select * from cte 


--This is where the magic happens. The while loop uses the fact that all 
children were given a level higher than 0 in the cte. 
While (select max(level) from @cte)>0 
BEGIN 
select @level = max(level) from @cte 
UPDATE @cte 
SET value = t.summe 

from @cte AS ctable inner join(
SELECT parentid, sum(case when dtable.operator = 0 then (-1 * dtable.value) 
when dtable.operator = 1 then dtable.value else 0 end) summe 
FROM @cte dtable 
group by parentid 
) 
as t 
on t.parentid = ctable.id 
WHERE level = @level -1 


--delete the rows, with the current max level. 
This causes the loop to work and acts like an i-- for my while function 
DELETE @cte 
FROM @cte ctable 
WHERE ctable.level = @level 

END 


SELECT @total = (select sum (value) from @cte); 
RETURN @total 
END