获取父项及其子项记录的总值

时间:2019-02-26 17:39:35

标签: sql sql-server tsql inner-join common-table-expression

我将非常感谢您提供有关如何获得父母及其子女总数的帮助。 我有两个表Units和UnitValues,一个表具有父子关系,第二个表仅具有关联值的子ID和父ID。我需要得到一个表,该表可以计算给定父母及其所有子女的总数。

我尝试了以下

;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')

它给出错误的结果。对于2KKKKK,计数应该为6,而不是2;对于1TTTTT,计数为15,而不是9。

+--------+-------------------+--------+
| 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     |
+--------+----------+------------+

UnitValues表

+-----+--------+---------+-------+------+
| 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 :(得分:0)

运行此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 
  
    
      

修订于2月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;  

答案 1 :(得分:0)

此查询应为您提供层次结构。如果要从其他表中获取信息,可以将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