Получить итоговые значения родительского и его дочерних записей - PullRequest
0 голосов
/ 26 февраля 2019

Буду признателен за любую помощь в том, как получить итоги по родителям и их детям.У меня есть две таблицы Units и UnitValues, одна имеет родительские и дочерние отношения, а вторая имеет только дочерние и родительские идентификаторы со связанными значениями.Мне нужно получить таблицу, которая вычисляет сумму для данного родителя и всех его детей.

Я пробовал следующее

;WITH tbl AS(
    SELECT ParentUnit,
    Sum(Value) AS Population,
    Sum(CASE WHEN Mark IN ('A','B') THEN Value ELSE 0 END) AS Mark
    FROM [TestDB].[dbo].[UnitValues] uv
    INNER JOIN [TestDB].[dbo].[Units] u
    On u.UnitID = uv.UnitID
    Group By ParentUnit
 )
 select * 
 from tbl
 where ParentUnit IN ('1TTTTT','2KKKKK')

Это дает неверный результат.Количество должно быть 6 вместо 2 для 2KKKKK и 15 вместо 9 для 1TTTTT.

+--------+-------------------+--------+
| Unit   | Population   |        Mark |
+--------+-------------------+--------+
| 1TTTTT |                 9 |      9 |
| 2KKKKK |                 2 |      2 |
+--------+-------------------+--------+

Таблица единиц измерения

+--------+----------+------------+
| UnitID |   Name   | ParentUnit |
+--------+----------+------------+
| 1TTTTT | Unit     | NULL       |
| 2KKKKK | Unit 1   | 1TTTTT     |
| 2LLLLL | Unit 2   | 1TTTTT     |
| 2NNNNN | Unit 3   | 1TTTTT     |
| 3KKKKG | Unit 1.2 | 2KKKKK     |
| 3KKKKS | Unit 1.1 | 2KKKKK     |
| 3LLLLL | Unit 2.1 | 2LLLLL     |
| 4LLLLL | Unit 2.2 | 3LLLLL     |
| 5LLLLL | Unit 2.3 | 4LLLLL     |
+--------+----------+------------+

Таблица единиц измерения

+-----+--------+---------+-------+------+
| ID  | UnitID | OtherId | Value | Mark |
+-----+--------+---------+-------+------+
| T12 | 1TTTTT | GGGGGG  |     1 |      |
| T22 | 2KKKKK | RRRRRR  |     1 | A    |
| T23 | 2KKKKK | RRRRRR  |     1 | A    |
| T24 | 2KKKKK | RRRRRR  |     1 | B    |
| T25 | 2KKKKK | RRRRRR  |     1 | A    |
| T31 | 2LLLLL | HHHHHH  |     1 | A    |
| T32 | 2LLLLL | HHHHHH  |     1 | A    |
| T33 | 2LLLLL | HHHHHH  |     1 | B    |
| T41 | 2NNNNN | HHHHHH  |     1 | A    |
| T42 | 2NNNNN | HHHHHH  |     1 | A    |
| T51 | 3KKKKG | BBBBBB  |     1 | A    |
| T52 | 3KKKKS | BBBBBB  |     1 | A    |
| T61 | 3LLLLL | BBBBBB  |     1 | A    |
| T71 | 4LLLLL | BBBBBB  |     1 | A    |
| T81 | 5LLLLL | BBBBBB  |     1 | A    |
+-----+--------+---------+-------+------+

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Этот запрос должен дать вам иерархию.Если вам нужна информация из другой таблицы, вы можете добавить JOIN к запросу.

;WITH cte AS (
    SELECT UnitID, ParentUnit, Name, 0 AS Level
    FROM Units
    WHERE ParentUnit IS NULL
    UNION ALL
    SELECT u.UnitID, u.ParentUnit, u.Name, Level + 1
    FROM Units u
    JOIN cte c ON u.ParentUnit = c.UnitID
 )
 SELECT *
 FROM cte
 ORDER BY Level
0 голосов
/ 26 февраля 2019

Когда я запускаю этот sql, я получаю эти результаты

 SELECT 
    'Units=' as t1
    ,u.*
    ,'Values=' as t2
    ,uv.*

    --FROM [TestDB].[dbo].[UnitValues] uv
    FROM [StackOver].[dbo].[GetTotal_UnitValues] as uv

    --INNER JOIN [TestDB].[dbo].[Units] u  
    INNER JOIN  [StackOver].[dbo].[GetTotal_Units] as u
    On u.UnitID = uv.UnitID

    --Trim used because of the way excel data inserted to sql with surrounding blanks
    WHERE rtrim(Ltrim(Mark)) IN ('A','B')
    and  rtrim(Ltrim(ParentUnit)) IN ('1TTTTT','2KKKKK')

t1       UnitID      Name        ParentUnit     t2       ID         UnitID OtherId  Value   Mark
Units=   2KKKKK      Unit 1      1TTTTT         Values=  T22     2KKKKK      RRRRRR     1    A    
Units=   2KKKKK      Unit 1      1TTTTT         Values=  T23     2KKKKK      RRRRRR     1    A    
Units=   2KKKKK      Unit 1      1TTTTT         Values=  T24     2KKKKK      RRRRRR     1    B    
Units=   2KKKKK      Unit 1      1TTTTT         Values=  T25     2KKKKK      RRRRRR     1    A    
Units=   2LLLLL      Unit 2      1TTTTT         Values=  T31     2LLLLL      HHHHHH     1    A    
Units=   2LLLLL      Unit 2      1TTTTT         Values=  T32     2LLLLL      HHHHHH     1    A    
Units=   2LLLLL      Unit 2      1TTTTT         Values=  T33     2LLLLL      HHHHHH     1    B    
Units=   2NNNNN      Unit 3      1TTTTT         Values=  T41     2NNNNN      HHHHHH     1    A    
Units=   2NNNNN      Unit 3      1TTTTT         Values=  T42     2NNNNN      HHHHHH     1    A    
Units=   3KKKKG      Unit 1.2    2KKKKK         Values=  T51     3KKKKG      BBBBBB     1    A    
Units=   3KKKKS      Unit 1.1    2KKKKK         Values=  T52     3KKKKS      BBBBBB     1    A 

исправлено 26 февраля 14:00 PST

-- Can only do one at a time, since some rows may satisfy both   
DECLARE @FindID varchar(255) = '1TTTTT';  -- 15
--DECLARE @FindID varchar(255) = '2KKKKK';  -- 6

With descendants as
  ( select ParentUnit, UnitID as descendant, 1 as level , name
    from [StackOver].[dbo].[GetTotal_Units]
  union all
    select d.ParentUnit, s.UnitID, d.level + 1 , d.name
    from descendants as d
      join [StackOver].[dbo].[GetTotal_Units]s
        on d.descendant = s.ParentUnit
  ) 
select *
from descendants ddd
Inner Join [StackOver].[dbo].[GetTotal_UnitValues] uv
On ddd.descendant = uv.UnitID

Where (ParentUnit = @FindID
 Or descendant = @FindID)
 And ParentUnit is not null

Order by  ParentUnit , descendant, level;  
...