Группировка Иерархические данные (parentID + ID) и промежуточная сумма? - PullRequest
1 голос
/ 04 февраля 2010

У меня есть следующие данные:

ID    parentID    Text        Price
1                 Root
2     1           Flowers
3     1           Electro
4     2           Rose        10
5     2           Violet      5
6     4           Red Rose    12
7     3           Television  100
8     3           Radio       70
9     8           Webradio    90

Я пытаюсь сгруппировать эти данные с Reporting Services 2008, и у меня есть сумма цены для группы уровня 1 (Цветы / Электро) и для уровня 0 (Корень).

У меня есть таблица, сгруппированная по [ID] с рекурсивным родителем [parendID], и я могу вычислить сумму для уровня 0 (только еще одна строка в таблице вне группы), но почему-то я возможность создавать суммы на группу, так как SRSS «создает» группы на уровень. Мой желаемый результат выглядит так:

ID    Text        Price
1     Root
|2    Flowers
|-4   Rose        10
|-5   Violet      5
| |-6 Red Rose    12
|     Group Sum-->27
|3    Electro
|-7   Television  100
|-8   Radio       70
  |-9 Webradio    90
      Group Sum-->260
----------------------
Total             287

(добавлен отступ ID для уточнения уровня)

При моем текущем подходе я не могу получить групповые суммы, поэтому я решил, что мне понадобится следующая структура данных:

ID    parentID    Text        Price    level0    level1    level2    level3
1                 Root                 1
2     1           Flowers              1         1
3     1           Electro              1         2
4     2           Rose        10       1         1         1
5     2           Violet      5        1         1         2
6     4           Red Rose    12       1         1         1         1
7     3           Television  100      1         2         1
8     3           Radio       70       1         2         2
9     8           Webradio    90       1         2         2         1

При наличии вышеуказанной структуры я могу создать внешнюю группировку уровня 0 с дочерними группировками уровня 1, уровня 2, уровня 3 соответственно. Когда у меня теперь есть «групповая сумма» на уровне 1 и общая сумма вне группы, я получаю ТОЧНО то, что хочу.

У меня следующий вопрос: Как мне достичь желаемого результата с моей текущей структурой данных или как временно преобразовать мою текущую структуру данных (внешние левые соединения?) В «новую структуру данных», чтобы я мог запустить свой отчет вне временной таблицы?

Спасибо, что нашли время, Dennis

Ответы [ 2 ]

1 голос
/ 04 февраля 2010
WITH    q AS
        (
        SELECT  id, parentId, price
        FROM    mytable
        UNION ALL
        SELECT  p.id, p.parentID, q.price
        FROM    q
        JOIN    mytable p
        ON      p.id = q.parentID
        )
SELECT  id, SUM(price)
FROM    q
GROUP BY
        id

Обновление:

Тестовый скрипт для проверки:

DECLARE @table TABLE (id INT NOT NULL PRIMARY KEY, parentID INT, txt VARCHAR(200) NOT NULL, price MONEY)

INSERT
INTO @table
SELECT 1, NULL, 'Root', NULL
UNION ALL
SELECT 2, 1, 'Flowers', NULL
UNION ALL
SELECT 3, 1, 'Electro', NULL
UNION ALL
SELECT 4, 2, 'Rose', 10
UNION ALL
SELECT 5, 2, 'Violet', 5
UNION ALL
SELECT 6, 4, 'Red Rose', 12
UNION ALL
SELECT 7, 3, 'Television', 100
UNION ALL
SELECT 8, 3, 'Radio', 70
UNION ALL
SELECT 9, 8, 'Webradio', 90;

WITH    q AS
        (
        SELECT  id, parentId, price
        FROM    @table
        UNION ALL
        SELECT  p.id, p.parentID, q.price
        FROM    q
        JOIN    @table p
        ON      p.id = q.parentID
        )
SELECT  t.*, psum
FROM    (        
        SELECT  id, SUM(price) AS psum
        FROM    q
        GROUP BY
                id
        ) qo
JOIN    @table t
ON      t.id = qo.id

Вот результат:

1       NULL    Root            NULL    287,00
2       1       Flowers         NULL    27,00
3       1       Electro         NULL    260,00
4       2       Rose            10,00   22,00
5       2       Violet          5,00    5,00
6       4       Red Rose        12,00   12,00
7       3       Television      100,00  100,00
8       3       Radio           70,00   160,00
9       8       Webradio        90,00   90,00
0 голосов
/ 08 февраля 2010

Я нашел действительно безобразный способ делать то, что я хочу - может быть, есть что-то лучше?

SELECT A.Text, A.Price,                   
  CASE
    WHEN D.Text IS NULL
    THEN
        CASE
            WHEN C.Text IS NULL
            THEN
                CASE
                    WHEN B.Text IS NULL
                    THEN
                        A.ID
                    ELSE B.ID
                END
            ELSE C.ID
            END
    ELSE D.ID
  END
  AS LEV0,

  CASE
    WHEN D.Text IS NULL
    THEN
        CASE
            WHEN C.Text IS NULL
            THEN
                CASE
                    WHEN B.Text IS NULL
                    THEN
                        NULL
                    ELSE A.ID
                END
            ELSE B.ID
            END
    ELSE C.ID
  END
  AS LEV1,

  CASE
    WHEN D.Text IS NULL
    THEN
        CASE
            WHEN C.Text IS NULL
            THEN
                NULL
            ELSE A.ID
            END
    ELSE B.ID
  END
  AS LEV2,

  CASE
    WHEN D.Text IS NULL
    THEN NULL
    ELSE A.ID
  END
  AS LEV3

FROM         dbo.testOld AS A LEFT OUTER JOIN
                  dbo.testOld AS B ON A.parentID = B.ID LEFT OUTER JOIN
                  dbo.testOld AS C ON B.parentID = C.ID LEFT OUTER JOIN
                  dbo.testOld AS D ON C.parentID = D.ID

Вывод этого:

Text       Price       LEV0        LEV1        LEV2        LEV3
---------- ----------- ----------- ----------- ----------- -----------
Root       NULL        1           NULL        NULL        NULL
Flowers    NULL        1           3           NULL        NULL
Electro    NULL        1           4           NULL        NULL
Television 100         1           4           5           NULL
Radio      70          1           4           6           NULL
Rose       10          1           3           7           NULL
Violet     5           1           3           8           NULL
Webradio   90          1           4           5           14
Red Rose   12          1           3           7           15

С помощью этой структуры я могу создать 4 вложенные группы в столбцах LEV0-3, включая промежуточные итоги на группу (как показано выше в моем желаемом результате).

...