2016-04-13 2 views
0

У меня есть следующие записи:Рекурсивного CTE ... дело с вложенными родителями/дети записывают

Моя цель состоит в том, чтобы проверить сумму детей для каждого родителя и убедитесь, что это 1 (или 100%).

В приведенном выше примере, у вас есть первый родитель:

Он имеет 2 детей:

Ребенок (теперь родитель) 12484 имеет ребенка 12486. Ребенок здесь (12486) имеет процент 0,6 (что не составляет 100%). Это НЕ ОК.

Ребенок (теперь родитель) 12485 имеет ребенка 12487. Ребенок здесь (12487) имеет процент 1 (или 100%). Хорошо.

Мне нужно суммировать проценты каждого вложенного ребенка и получить это значение, потому что оно не суммируется до 100%, тогда мне нужно отобразить сообщение. У меня с трудом возникает запрос на это. Может кто-нибудь дать мне руку?

Это то, что я пробовал, и я получаю «Утверждение завершено. Максимальная рекурсия 100 исчерпана до завершения заявки». сообщение об ошибке.

with cte 
      as (select cp.parent_payee_id, 
         cp.payee_id, 
         cp.payee_pct, 
         0 as level 
       from dbo.tp_contract_payee cp 
       where cp.participant_id = 12067 
         and cp.payee_id = cp.parent_payee_id 
       union all 
       select cp.parent_payee_id, 
         cp.payee_id, 
         cp.payee_pct, 
         c.level + 1 as level 
       from dbo.tp_contract_payee cp 
       inner join cte c 
       on  cp.parent_payee_id = c.payee_id 
       where cp.participant_id = 12067 
      ) 
    select * 
    from cte 

ответ

2

Я считаю, что-то вроде следующего должно работать:

WITH RECURSIVE recCTE AS 
(
    SELECT 
     parent_payee_id as parent, 
     payee_id as child, 
     payee_pct 
     1 as depth, 
     parent_payee_id + '>' + payee_id as path 
    FROM 
     table 
    WHERE 
     --top most node 
     parent_payee_id = 12043 
     AND payee_id <> parent_payee_id --prevent endless recursion 

    UNION ALL 

    SELECT 
     table.parent_payee_id as parent, 
     table.payee_id as child, 
     table.payee_pct, 
     recCTE.depth + 1 as Depth, 
     recCTE.path + '>' + table.payee_id as path 
    FROM 
     recCTE 
     INNER JOIN table ON 
      recCTE.child = table.parent_payee_id AND 
      recCTE.child <> table.payee_id --again prevent records where parent is child 
    Where depth < 15 --prevent endless cycles 
) 

SELECT DISTINCT parent 
FROM recCTE 
GROUP BY parent 
HAVING sum(payee_pct) <> 1; 

Это отличается от вашего главным образом в WHERE заявления на обоих рекурсивных Seed (запроса перед UNION) и рекурсивной срок (запрос после UNION). Я считаю, что ваш слишком ограничительный, особенно в рекурсивный термин, так как вы хотите разрешить записи, которые являются дочерними элементами 12067, но тогда вы разрешаете только 12067 в качестве родительского идентификатора.

Здесь, однако, мы тянем каждый потомок 12043 (из вашей таблицы примеров), и это payee_pct. Затем мы анализируем каждого родителя в окончательном SELECT и сумме всех его payee_pcts, которые по сути являются первой дочерней суммой родителя (payee_pct). Если какой-либо из них не равен 1, то мы выводим родительский элемент на выходе.

Во всяком случае, между вашим запросом и моим, я бы предположил, что это довольно близко к требованиям, поэтому должно быть хитрости, чтобы получить именно то, что вам нужно, если это не делает трюк.

Смежные вопросы