Domanda

I am using T-SQL in SQL Server and have the following "TEST" table:

CHILD       PARENT      VAL         WEIGHTAGE
============================================================
abcd        yz          NULL        1
efgh        abcd        NULL        1
ijkl        abcd        70          1
mnop        NULL        5           1
qrst        efgh        100         1
uvwx        efgh        200         -1
yz          NULL        NULL        1

The "CHILD" column contains all labels to be displayed. The "PARENT" column signifies the recursive parent-child relationship.

For example, "yz" is the parent of "abcd". "abcd" in turn, is parent of "efgh" and "ijkl". "efgh", also, in turn, is parent of "qrst" and "uvwx".

The values which appear only in "CHILD" (but not in "PARENT") can be loaded from database. Now, I want to automatically calculate the remaining "NULL" values automatically based on the recursive parent child relationship.

So, the final query output would be calculated as follows (it also utilizes the "WEIGHTAGE" column for calculation):

CHILD       PARENT      VAL                 WEIGHTAGE
==========================================================================
abcd        yz          (-100+70)=-30       1
efgh        abcd        (100-200) = -100    1
ijkl        abcd        70                  1
mnop        NULL        5                   1
qrst        efgh        100                 1
uvwx        efgh        200                 -1
yz          NULL        -30                 1

Appreciate your help. Thanks.

È stato utile?

Soluzione

Here's an example recursive CTE. Your column child refers to the name of the current row, and not to it's child. That confused me so I renamed the column from child to name.

; with  CTE as
        (
        select  name as root
        ,       name
        ,       parent
        ,       val * weightage as change
        from    test
        union all
        select  parent.root
        ,       child.name
        ,       child.parent
        ,       child.val * child.weightage as change
        from    CTE parent
        join    test child
        on      child.parent = parent.name 
        )
select  root
,       sum(change) as val
from    CTE
group by
        root

This prints:

abcd   -30
efgh   -100
ijkl   70
mnop   5
qrst   100
uvwx   -200
yz     -30

See it working at SQL Fiddle.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top