таблица со ссылками на себя с дочерней таблицей - PullRequest
5 голосов
/ 04 января 2012

У меня есть таблица со ссылками, подобная этой:

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

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

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

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

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?Заранее спасибо.

Ответы [ 2 ]

5 голосов
/ 04 января 2012

РЕДАКТИРОВАТЬ Все агрегации перемещены из CTE

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
1 голос
/ 04 января 2012

Вот оно:

Давайте предложим эту схему:

​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), а затем запрос суммирует все продажи для этих «листьев». Вы можете проверить это, запустив .

EDITED

Запрос исправлен.

...