2012-01-03 1 views
5

У меня есть автореферентная таблица с содержанием, как это:самостоятельно реферирование стола с ребенком таблицей

Self-referencing parent table 
ID ParentID Name 
--------------------- 
1    John 
2 1   Mike 
3 2   Erin 
4 1   Janie 
5    Eric 
6 5   Peter 

Иерархия дерева должна выглядеть следующим образом

  • Джон
    • Майк
      • Erin
    • Джени
  • Эрик
    • Питер

И стол ребенок, который хранит лист родительской таблицы, которая выглядит следующим образом:

ID Sales 
3 100 
3 100 
4 200 
4 200 
6 300 
6 300 
6 300 

Я пытаясь свернуть сумму от листового узла до иерархии, чтобы она возвращалась как. .

ID Name Sum 
1 John 800 
2 Mike 200 
3 Erin 200 
4 Janie 400 
5 Eric 900 
6 Peter 900 

Любые идеи, как достичь этого в sql 2008? Заранее спасибо.

ответ

5

EDIT Все агрегация вышла из КТРА

WITH 
    tree AS 
(
    SELECT 
    id    AS root_id, 
    name    AS root_name, 
    id    AS leaf_id 
    FROM 
    yourTreeTable 

    UNION ALL 

    SELECT 
    tree.root_id  AS root_id, 
    tree.name   AS root_name, 
    yourTreeTable.id AS leaf_id 
    FROM 
    tree 
    INNER JOIN 
    yourTreeTable 
     ON tree.leaf_id = yourTreeTable.ParentID 
) 
SELECT 
    tree.root_id, 
    tree.root_name, 
    COALESCE(SUM(yourScoresTable.score), 0) AS total 
FROM 
    tree 
LEFT JOIN 
    yourScoresTable 
    ON yourScoresTable.ID = tree.leafID 
GROUP BY 
    tree.root_id, 
    tree.root_name 
+0

Спасибо за ответ, Дем. Я получаю два сообщения об ошибке с этим запросом: 'GROUP BY, HAVING или агрегированные функции не разрешены в рекурсивной части рекурсивного общего выражения таблицы 'flattend'.' И 'Outer join не допускается в рекурсивной части рекурсивное общее табличное выражение «flattend». '. Есть идеи? – Eric

+0

@ Эрик - Я так не практиковался, что даже не помню, что это было так. Я перекодировал так, что вся агрегирование выполняется за пределами CTE. – MatBailie

+0

Извините за поздний ответ, вчера мне пришлось уйти, и я весь день встречался. Запрос работает как шарм. Но мне не удалось понять CTE и как работает функция COALESCE. Мне нужно добавить столбец ParentID в результат, чтобы я мог восстановить древовидную структуру в приложении, но я продолжаю получать разные значения. Можете ли вы помочь немного больше? Еще раз спасибо. – Eric

1

Здесь:

Давайте supose этой схемы:

​create table #parent (
ID int, 
ParentID int, 
Name varchar(50)); 

create table #child (
ID int, 
Sales int); 

Запроса само объяснил:

WITH 
    tree AS 
(
    SELECT 
    id as id_parent, 
    id as id 
    FROM 
    #parent 
    UNION ALL 
    SELECT 
    tree.id_parent as id_parent, 
    #parent.id AS id 
    FROM 
    tree 
    INNER JOIN 
    #parent  
     ON tree.id = #parent.ParentID 
) 
SELECT 
    #parent.id, 
    #parent.name, 
    COALESCE(SUM(#child.Sales), 0) AS total 
FROM 
    #parent 
LEFT JOIN 
    tree 
    ON #parent.ID = tree.id_parent 
LEFT JOIN 
    #child on tree.id = #child.id 
GROUP BY 
    #parent.id, 
    #parent.name 

CTE возвращает список «листьев» для каждого сотрудника (#parent), затем запрос суммирует все продажи для этого «листа». You can test it running.

EDITED

Запрос фиксирована.

+0

спасибо за ответ.Я попытался выполнить запрос, но заметил, что сумма корневого узла неверна. Сумма для Джона должна составлять 800 вместо 400. – Eric

+0

@ Эрик, Исправлено. Но будьте осторожны, сумма Джона равна 600 не 800 (jhon = 0, Mike = 0, Erin = 100 + 100, Janie = 200 + 200) – danihp

+0

мой плохой. спасибо за исправление этого. Я потратил слишком много часов на эту проблему, и я наконец получил то, что мне нужно. еще раз спасибо. – Eric

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