【问题标题】:Sum hierarchical values in table for Continent, countries and states在表格中为大陆、国家和州求和层次值
【发布时间】:2016-03-09 06:40:11
【问题描述】:

考虑人口结构。

Asia(100+50+150=300)
    > China (20+80=100)
        >   China_StateA (20)
        >   China_StateB (80)
    > KSA (10+40=50)
        >   KSA_StateA (10)
        >   KSA_StateB (40) 
    > India (70+80=150)
        >   India_StateA (70)
        >   India_StateB (80)   


Europe(50+15=65)
    > England (50)
        >   England_StateA (20)
        >   England_StateB (30)
    > Ireland (5+10=15)
        >   Ireland_StateA (5)
        >   Ireland_StateB (10)

如果我在单个数据库表中具有相同的结构,如下所示

Id  Type    Name    ParentId    Population
1   Continent   Asia    0   
2   Country China   1   
3   State   China_StateA    2   20
4   State   China_StateB    2   80
5   Country KSA 1   
6   State   KSA_StateA  5   10
7   State   KSA_StateB  5   40
8   Country India   1   
9   State   India_StateA    8   70
10  State   India_StateB    8   80
11  Continent   Europe  0   
12  Country England 11  
13  State   England_StateA  12  20
14  State   England_StateB  12  30
15  Country Ireland 11  
16  State   Ireland_StateA  15  5
17  State   Ireland_StateB  15  10

那么我该如何编写一个 sql 查询来返回每个级别的人口。即将总结州的人口以找到国家的人口。 同样将总结国家人口以找到大陆人口。

【问题讨论】:

  • 我猜您将“州”条目与“国家”条目的名称相关联。但是,您如何将大陆与国家联系起来?通过订购 ID 字段?我认为实现您想要的最简单的方法是通过函数或存储过程并遍历游标:msdn.microsoft.com/es-es/library/ms180169(v=sql.120).aspx
  • 有什么办法可以查出哪个国家属于哪个大陆,哪个州属于哪个国家?我的意思是我们中的一些人知道印度在亚洲,但数据库不知道。
  • 更新评论:使用hierarchical queries

标签: sql sql-server database oracle


【解决方案1】:

如果你想在大洲之后求和,一种方法是添加一列大洲

大陆之后的总和是

SELECT sum(Population) FROM yourTable GROUP BY continent. 

另一种方法是使用硬编码列表

各大洲后的总和

只需将sumgroup byREGEXP_SUBSTR 与in 和硬编码列表一起使用。在我的例子中,德国应该代表欧洲。

SELECT sum(Population) FROM yourTable GROUP BY REGEXP_SUBSTR('Name','(.*)_?') IN ('England', 'Germany')

【讨论】:

  • 此解决方案将为他提供国家/地区的摘要,而不是大陆的摘要。
  • @Rumpelstinsk 非常感谢您的通知。刚到凌晨。我更新了我的答案。
【解决方案2】:

你可以使用 CTE 来做到这一点

WITH CTE_TMP
AS
(
    SELECT  Id,[Type],Name,ParentId,[Population]
    FROM    MyTable
    WHERE   [Type]  =   'State'
    UNION ALL
    SELECT  M.Id,M.[Type],M.Name,M.ParentId,ISNULL(C.[Population],0)
    FROM    MyTable M
    INNER JOIN CTE_TMP C ON M.Id = C.ParentId
)
SELECT Id,[Type],Name,ParentId,SUM([Population]) AS [Population] 
FROM CTE_TMP 
GROUP BY Id,[Type],Name,ParentId
ORDER BY id

【讨论】:

  • 不错。一个小错误:你在声明的开头有一个流浪的;
  • 谢谢你弗兰克施密特
【解决方案3】:

如果您想在不同的视图或特定国家/地区获取国家和大洲的数据,Kordi 的解决方案将为您提供帮助。但是,如果您想在一个视图中查看所有内容,并且您的层次结构中只有 2 个级别,则可以使用此查询。

SELECT parent.Id
    parent.Name,
    parent.ParentId
    SUM(childs.Population)
FROM mytable parent
    INNER JOIN mytable childs ON parent.Id = childs.ParentId
WHERE parent.Type = 'Continent'
GroupBy parent.Id, parent.Name, parent.ParentId

UNION

SELECT parent.Id
    parent.Name,
    parent.ParentId
    SUM(childs.Population)
FROM mytable parent
    INNER JOIN mytable childs ON parent.Id = childs.ParentId
WHERE parent.Type = 'Country'
GroupBy parent.Id, parent.Name, parent.ParentId

注意:如果您有超过 2 个层次结构级别,则此查询的 2 个解决方法是,使用 XML PATH 或存储过程或函数中的游标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-22
    • 2017-10-03
    • 2018-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多