SQL 2012 - 公用表表达式 - 层次结构 - 列出父母之前的所有子项

时间:2012-09-04 02:57:09

标签: sql sql-server hierarchy common-table-expression sql-server-2012

我有一个问题,我正在尝试解决这个问题,我认为这与我在这里研究的其他SQL邻接列表层次结构问题不同。我正在尝试对数据进行排序,以便所有孩子都在他们的父母之前列出。我已经有了CTE,它返回给定ParentID的所有子节点以及给定ChildID的所有父节点,但那些不符合我当前的需要。

我有两张桌子:

CREATE TABLE [dbo].[ItemMaster](
[ItemID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,

CREATE TABLE [dbo].[References](
[RefID] [int] IDENTITY(1,1) NOT NULL,
[ParentID] [int] NOT NULL,
[ChildID] [int] NOT NULL,

ItemMaster.ItemID与References.ParentID和References.ChildID

之间存在外键关系

以下是我表中的一些示例数据......

ItemID,名称

  • 1,A1
  • 2,A2
  • 3,A3
  • 4,P1
  • 5,P2
  • 6,P3
  • 7,P4
  • 8,TOP

RefID,ParentID,ChildID

  • 1,1,5-
  • 2,2,5-
  • 3,2,6
  • 4,3,2
  • 5,7,3
  • 6,8,4
  • 7,8,1
  • 8,8,2
  • 9,8,3
  • 10,8,7

我想要的输出会列出每个ItemID和Name以及在任何父项之前列出的子项。像这样......

ItemID,名称

  • 4,P1
  • 5,P2
  • 6,P3
  • 1,A1
  • 2,A2
  • 3,A3
  • 7,P4
  • 8,Top

注意:

  • 任何ItemID都可以包含0,1或> 1个父母。
    • 那些没有父母的人将列在输出的顶部。
  • 我没有参考表中“最顶层父母”的NULL值。

我希望我已经给出了足够的细节,并对自己做了很好的解释,以获得一些反馈。任何想法将不胜感激!

1 个答案:

答案 0 :(得分:1)

我认为实现这一目标的方法是使用递归操作并根据所有子节点的权重为每个节点分配权重。

例如,此树中的任何叶子的权重都为零,因为它没有任何子项。它的直接父母将是1,而父母的父母将是2,依此类推。对重量进行排序应该返回您需要的结果集。这是我用来测试我的理论的递归函数:

CREATE FUNCTION [dbo].[GetItemWeight](@ItemID int)
RETURNS int
BEGIN

DECLARE @Weight int;

SELECT
  @Weight = COUNT(ParentID) 
FROM
  [References]
WHERE
  ChildID = @ItemID;

SELECT
  @Weight = ISNULL(@Weight, 0) + SUM(dbo.GetItemWeight(ChildID))
FROM
  [References]
WHERE
  ParentID = @ItemID;

RETURN ISNULL(@Weight, 0);
END

这将返回您发布的结果集:

SELECT ItemID, Name FROM ItemMaster ORDER BY dbo.GetItemWeight(ItemID);

祝你好运:)