【问题标题】:MySQL Group By Lowest Common Parent IDMySQL 按最低公共父 ID 分组
【发布时间】:2012-04-20 17:55:25
【问题描述】:

我有一个包含IDAmountParent_ID 的表。 (实际上它有点复杂,但这是本示例的所有重要列)。基本上我想做的是按最低的公共父级(即父级ID为NULL的父级)对Amount列进行分组和求和。

ID  Amount  Parent_ID
1   100     NULL
2   150     1
3   50      1
4   75      3
5   25      4
6   125     NULL
7   50      6
8   50      7
9   100     8

预期结果:

ID  SUM
1   400
6   325

如您所见,它只返回两条记录,即没有父项的记录,这意味着它们是顶级项目。 Sum 列是其所有子级的 Amount 的总和,因此 ID = 1 是 1,2,3,4 和 5 的总和。ID = 6 是 6,7 的总和, 8 和 9。

【问题讨论】:

  • 是否有设定的嵌套数?即你是在 5 点停止还是会一直持续下去?
  • 理论上它可以永远持续下去,但如果没有解决方案让它永远持续下去,我想我可以选择一个只能到 5 左右的解决方案。
  • 测试设置环境:sqlfiddle.com/#!2/b7a79
  • 许多关于针对 MySQL 的递归查询的问题...如果没有实际的存储过程来处理链上的每个递归级别,就无法完成。
  • MySQL 不支持分层查询。 forums.mysql.com/read.php?113,136927,155954#msg-155954 将给出一些指示,这里也有一些关于 SO 的示例。现在查找它们...和stackoverflow.com/questions/5749385/…

标签: mysql


【解决方案1】:

如果您可以定义层次结构中的级别数量限制,则可以将此解决方案扩展到任意数量的级别:

select
    coalesce(t5.ID,t4.ID,t3.ID,t2.ID,t1.ID) as Root,
    sum(t1.Amount) as Amount
from Table1 t1
left join Table1 t2 on t1.Parent_ID = t2.ID
left join Table1 t3 on t2.Parent_ID = t3.ID
left join Table1 t4 on t3.Parent_ID = t4.ID
left join Table1 t5 on t4.Parent_ID = t5.ID
group by Root

只需根据需要添加更多left join 并将它们添加到coalesce 中的列列表中。

演示:http://www.sqlfiddle.com/#!2/b7a79/17

【讨论】:

  • 很好的答案。我想给你+2。一个用于合并,我以前从未见过,另外一个用于 sqlfiddle。多么棒的工具!
  • 好的,这是一个很好的解决方法,但我看到了一个奇怪的错误。在我的表中,我还有一个名称列,我想与查询一起选择它。问题是当我选择名称时它也是错误的(选择的名称与具有根 id 的项目的名称不同)。请参阅此示例(请注意,我必须重新排列插入才能发生这种情况):sqlfiddle.com/#!2/dbd58/1
  • 没关系,看来我还需要合并名称:coalesce(t5.Name,t4.Name,t3.Name,t2.Name,t1.Name) as Namesqlfiddle.com/#!2/dbd58/4
【解决方案2】:

要实现您正在寻找的内容,您需要一个递归存储过程,因为您不希望某些东西会限制您的结构深度。

我认为更改数据结构会更容易。添加一列,将每个子级与其顶级父级关联起来。这样你就可以通过简单的GROUP BY 得到你想要的。

【讨论】:

    猜你喜欢
    • 2020-02-15
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-26
    相关资源
    最近更新 更多