2010-02-04 3 views
1

У меня есть следующие данные:Группировка Иерархических данных (parentID + ID) и текущей суммы?

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 (Цветы/Electro) и для уровня 0 (Root) ,

У меня есть таблица, сгруппированная по [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 

при наличии вышеуказанной конструкции можно создать внешнюю группировку level0, с детьми группировок level1, level2, LEVEL3 соответственно. Когда теперь, имея «групповую сумму» на уровне 1, а общая сумма вне группы, я ТОЧНО, что хочу.

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

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

+0

Есть ли предел рекурсии, которую вы можете иметь? Вы упомянули 4 уровня в своем примере. Если он ограничен, вы можете вслепую левый присоединиться 4 раза, иначе вам, вероятно, придется сделать функцию или добавить столбец «LevelNumber». –

+0

4 уровня являются максимальными, я должен был указать, что –

+0

Думаете, вы можете получить больше ответов, если вы пометите его как «t-sql». –

ответ

0

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

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 столбцов, включая подытогами на группу (как показано выше в моем желаемого результата) ,

1
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 

Update:

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

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

, но все, что я получаю с этим, - это сумма текущего идентификатора - без сгруппированного вывода. Мой выход (замена ID текстом): телевизор 100, радио 70, фиолетовый 5 и т. Д., Поэтому в основном просто цена предмета. SSMS 2008 преобразовал запрос С д AS (SELECT Text, ParentID, Цена ОТ dbo.testOld UNION ALL ВЫБРАТЬ p.Text, p.parentID, NULL AS nullablecolumn ИЗ д КАК Q_2 INNER JOIN dbo.testOld AS p ON p.ID = q_2.parentID) SELECT Text, SUM (Цена) AS sumprice FROM q AS q_1 GROUP BY Текст –

+0

@moontear: справа, в запросе была небольшая ошибка. См. Обновление сообщения. – Quassnoi

+0

Некоторое серьезное мастерство SQL прямо там! К сожалению, это не то решение, которое я ищу. Вы предлагаете правильный способ создания сумм на уровне иерархии, но мне действительно нужен способ создания группировок на уровне иерархии. Мне нужно иметь возможность группировать за уровень, чтобы я мог позволить службам отчетности заботиться о вычислении сумм. Это возможно с моей второй структурой данных примера - у меня просто нет этой структуры, и мне нужен способ временно создать эту структуру или каким-то образом поручить службам отчетности использовать разные группы. –