1

ここで調査した他の SQL 隣接リスト階層の問題とは異なると思われる解決しようとしている問題があります。すべての子が親の前にリストされるようにデータを並べ替えようとしています。特定の ParentID のすべての子と特定の ChildID のすべての親を返す CTE を既に持っていますが、それらは現在のニーズに適合しません。

私は2つのテーブルを持っています:

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 の間には外部キー関係が存在します。

これが私のテーブルのデータの例です...

アイテムID、名前

  • 1、A1
  • 2、A2
  • 3、A3
  • 4、P1
  • 5、P2
  • 6、P3
  • 7、P4
  • 8、トップ

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 がリストされます。このような...

アイテムID、名前

  • 4、P1
  • 5、P2
  • 6、P3
  • 1、A1
  • 2、A2
  • 3、A3
  • 7、P4
  • 8、トップ

ノート:

  • ItemID は、0、1、または > 1 の親を持つことができます。
    • 親を持たないものは、出力の一番上に表示されます。
  • 参照テーブルの「最上位の親」に NULL 値がありません。

フィードバックを得るのに十分な詳細を提供し、十分に説明できたことを願っています。どんなアイデアでも大歓迎です!

4

1 に答える 1

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

頑張ってください:)

于 2012-09-04T04:55:13.793 に答える