1

I国 このツリー誤った結果

  • をしました
    • リージョン
        • 協会
          • センター
            • 学校
              • クラス

enter image description here

私は= 1

ユーザーIDのために、このクエリを実行する場合、それは=(それがユーザーA =ユーザーIDの下にあるすべてのユーザーを持って来る私に正しいデータを提供します、ここで

;WITH MyCTE AS 
(
    SELECT T1.ID, UserId, NULL AS PARENT_ID, T1.GroupID, G.EntityLevelID 
    FROM UserJobs T1 
    INNER JOIN [GROUP] G ON T1.GROUPID = G.ID 
    inner join EntityLevel el on G.EntityLevelID = el.Id 
    WHERE T1.UserID = 1 

    UNION ALL 

    SELECT T2.ID, T2.UserId, EL.ParentID, T2.GroupID, G.EntityLevelID 
    FROM UserJobs T2 
    INNER JOIN [GROUP] G ON T2.GROUPID = G.ID 
    inner join EntityLevel el on G.EntityLevelID = el.Id 
    INNER JOIN MyCTE itms ON EL.ParentID >= itms.ID 
) 

SELECT B.*, C.*, A.* 
FROM (SELECT DISTINCT * FROM MyCTE) A 
INNER JOIN [USER] B ON A.UserID = B.ID 
INNER JOIN [Group] C ON A.GroupID = C.ID 
order by a.GroupID ; 

このクエリを持っています1)

1 UserA 1 Country Manager 1 1 1 NULL 1 1 
2 UserB 2 Region Manager 2 2 2 1 2 2 
8 UserH 2 Region Manager 2 8 8 1 2 2 
3 UserC 3 City Manager 3 3 3 2 3 3 
9 UserI 3 City Manager 3 9 9 2 3 3 
4 UserD 4 Association Manager 4 4 4 3 4 4 
10 UserJ 4 Association Manager 4 10 10 3 4 4 
5 UserE 5 Center Manager 5 5 5 4 5 5 
6 UserF 6 School Manager 6 6 6 5 6 6 
7 UserG 7 Teacher 7 7 7 6 7 7 

これは私が探しているものを実際にですが、私は同じUserI IDの下でユーザーを取得する必要があるときに問題が来るはそうUserJ

である彼の下で一人のユーザーを持っているので、

9 UserI 3 City Manager 3 9 9 NULL 3 3 
    10 UserJ 4 Association Manager 4 10 10 NULL 4 4 

同じエラーが発生するように、結果必見の外観

9 UserI 3 City Manager 3 9 9 NULL 3 3 

、それは間違っている:0

結果がありますUserID = 3これは私にUserJを与えます。ツリー


スクリプトとデータがここにある:

CREATE TABLE [dbo].[Assocation](
    [ID] [int] NOT NULL, 
    [Name] [nvarchar](50) NULL, 
    [CityID] [int] NULL, 
CONSTRAINT [PK_Assocation] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
/****** Object: Table [dbo].[Center] Script Date: 2017-04-04 8:33:43 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[Center](
    [ID] [int] NOT NULL, 
    [Name] [nvarchar](50) NULL, 
    [AssociationID] [int] NULL, 
CONSTRAINT [PK_Center] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
/****** Object: Table [dbo].[City] Script Date: 2017-04-04 8:33:43 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[City](
    [ID] [int] NOT NULL, 
    [Name] [nvarchar](50) NULL, 
    [RegionID] [int] NULL, 
CONSTRAINT [PK_City] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
/****** Object: Table [dbo].[Class] Script Date: 2017-04-04 8:33:43 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[Class](
    [ID] [int] NOT NULL, 
    [Name] [nvarchar](50) NULL, 
    [SchoolID] [int] NULL, 
CONSTRAINT [PK_Class] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
/****** Object: Table [dbo].[Country] Script Date: 2017-04-04 8:33:43 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[Country](
    [ID] [int] NOT NULL, 
    [Name] [nvarchar](50) NULL, 
CONSTRAINT [PK_Country] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
/****** Object: Table [dbo].[EntityLevel] Script Date: 2017-04-04 8:33:43 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[EntityLevel](
    [ID] [int] NOT NULL, 
    [Name] [nvarchar](50) NULL, 
    [ParentID] [int] NULL, 
CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
/****** Object: Table [dbo].[Group] Script Date: 2017-04-04 8:33:43 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[Group](
    [ID] [int] NOT NULL, 
    [Name] [nvarchar](50) NULL, 
    [EntityLevelID] [int] NULL, 
CONSTRAINT [PK_Group] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
/****** Object: Table [dbo].[Region] Script Date: 2017-04-04 8:33:43 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[Region](
    [ID] [int] NOT NULL, 
    [Name] [nvarchar](50) NULL, 
    [CountryID] [int] NULL, 
CONSTRAINT [PK_Region] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
/****** Object: Table [dbo].[School] Script Date: 2017-04-04 8:33:43 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[School](
    [ID] [int] NOT NULL, 
    [Name] [nvarchar](50) NULL, 
    [CenterID] [int] NULL, 
CONSTRAINT [PK_School] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
/****** Object: Table [dbo].[User] Script Date: 2017-04-04 8:33:43 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[User](
    [ID] [int] NOT NULL, 
    [Name] [nvarchar](50) NULL, 
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
/****** Object: Table [dbo].[UserJobs] Script Date: 2017-04-04 8:33:43 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[UserJobs](
    [ID] [int] NOT NULL, 
    [UserID] [int] NOT NULL, 
    [GroupID] [int] NOT NULL, 
    [EntityID] [int] NOT NULL, 
CONSTRAINT [PK_UserJobs] PRIMARY KEY CLUSTERED 
(
    [ID] ASC, 
    [UserID] ASC, 
    [GroupID] ASC, 
    [EntityID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
INSERT [dbo].[Assocation] ([ID], [Name], [CityID]) VALUES (1, N'KH', 1) 
GO 
INSERT [dbo].[Assocation] ([ID], [Name], [CityID]) VALUES (2, N'mkh_ass', 2) 
GO 
INSERT [dbo].[Center] ([ID], [Name], [AssociationID]) VALUES (1, N'NorthCenter', 1) 
GO 
INSERT [dbo].[Center] ([ID], [Name], [AssociationID]) VALUES (2, N'SouthCenter', 1) 
GO 
INSERT [dbo].[City] ([ID], [Name], [RegionID]) VALUES (1, N'Jeddah', 1) 
GO 
INSERT [dbo].[City] ([ID], [Name], [RegionID]) VALUES (2, N'MakkahCiry', 1) 
GO 
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (1, N'Class1', 1) 
GO 
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (2, N'Class2', 1) 
GO 
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (3, N'class3', 2) 
GO 
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (4, N'class4', 2) 
GO 
INSERT [dbo].[Country] ([ID], [Name]) VALUES (1, N'KSA') 
GO 
INSERT [dbo].[Country] ([ID], [Name]) VALUES (2, N'UAE') 
GO 
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (1, N'Country', NULL) 
GO 
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (2, N'Region', 1) 
GO 
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (3, N'City', 2) 
GO 
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (4, N'Association', 3) 
GO 
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (5, N'Center', 4) 
GO 
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (6, N'School', 5) 
GO 
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (7, N'Class', 6) 
GO 
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (1, N'Country Manager', 1) 
GO 
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (2, N'Region Manager', 2) 
GO 
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (3, N'City Manager', 3) 
GO 
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (4, N'Association Manager', 4) 
GO 
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (5, N'Center Manager', 5) 
GO 
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (6, N'School Manager', 6) 
GO 
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (7, N'Teacher', 7) 
GO 
INSERT [dbo].[Region] ([ID], [Name], [CountryID]) VALUES (1, N'Makkah', 1) 
GO 
INSERT [dbo].[Region] ([ID], [Name], [CountryID]) VALUES (2, N'Riyadh', 1) 
GO 
INSERT [dbo].[School] ([ID], [Name], [CenterID]) VALUES (1, N'School1', 1) 
GO 
INSERT [dbo].[School] ([ID], [Name], [CenterID]) VALUES (2, N'School2', 1) 
GO 
INSERT [dbo].[School] ([ID], [Name], [CenterID]) VALUES (3, N'School3', 2) 
GO 
INSERT [dbo].[User] ([ID], [Name]) VALUES (1, N'UserA') 
GO 
INSERT [dbo].[User] ([ID], [Name]) VALUES (2, N'UserB') 
GO 
INSERT [dbo].[User] ([ID], [Name]) VALUES (3, N'UserC') 
GO 
INSERT [dbo].[User] ([ID], [Name]) VALUES (4, N'UserD') 
GO 
INSERT [dbo].[User] ([ID], [Name]) VALUES (5, N'UserE') 
GO 
INSERT [dbo].[User] ([ID], [Name]) VALUES (6, N'UserF') 
GO 
INSERT [dbo].[User] ([ID], [Name]) VALUES (7, N'UserG') 
GO 
INSERT [dbo].[User] ([ID], [Name]) VALUES (8, N'UserH') 
GO 
INSERT [dbo].[User] ([ID], [Name]) VALUES (9, N'UserI') 
GO 
INSERT [dbo].[User] ([ID], [Name]) VALUES (10, N'UserJ') 
GO 
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (1, 1, 1, 1) 
GO 
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (2, 2, 2, 1) 
GO 
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (3, 3, 3, 1) 
GO 
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (4, 4, 4, 1) 
GO 
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (5, 5, 5, 1) 
GO 
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (6, 6, 6, 1) 
GO 
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (7, 7, 7, 1) 
GO 
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (8, 8, 2, 2) 
GO 
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (9, 9, 3, 2) 
GO 
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (10, 10, 4, 2) 
GO 

そのためのあらゆるソリューション...

+0

あなたの 'PARENT_ID'値は正しくありません。具体的には、UserJとUserIはどのようにデータにリンクされていますか? UserJがUserIにリンクされているか、UserIがUserJにリンクしているかを示す表とフィールドは何ですか? –

+0

@LaughingVergil彼らはUserJobs And Groups(グループ内にはentityLevelがあります)と一緒に関連していて、 'UserJ'は' City'レベルの 'UserI'の下にある' Association'に入っています。 – Loai

答えて

1

私はあなたのPARENT_ID値が正しくないことを繰り返すことになります。なぜUserI(ID = 9)クエリを詳細に見てみましょう。

SELECT T1.ID, UserId, NULL AS PARENT_ID, T1.GroupID, G.EntityLevelID 
    FROM #UserJobs T1 
    INNER JOIN #GROUP G ON T1.GROUPID = G.ID 
    inner join #EntityLevel el on G.EntityLevelID = el.Id 
    WHERE T1.UserID = 9 

UserIを処理するときにこれがあなたのデータに定義されているように、ベースのクエリになります(注:私はテストの後にクリーンアップを簡素化する代わりに永続テーブルの一時テーブルを使用)この照会フラグメントの出力は次のようになりますこれは

ID UserId PARENT_ID GroupID EntityLevelID 
9  9 NULL   3  3 

これまでのところ問題ありません。だから、あなたのCTEの再帰部分は次のとおりです。

UNION ALL 

    SELECT T2.ID, T2.UserId, EL.ParentID, T2.GroupID, G.EntityLevelID 
    FROM #UserJobs T2 
    INNER JOIN #GROUP G ON T2.GROUPID = G.ID 
    inner join #EntityLevel el on G.EntityLevelID = el.Id 
    INNER JOIN MyCTE itms 
     ON EL.ParentID >= itms.ID -- <<<< PROBLEM!! 

我々は上記を参照したように、このクエリの最初の部分のためのitms.IDの値がされた[9]。これは#EntityLevel.ParentIDフィールドの値に結合する必要があります。しかし、あなたが#EntityLevelテーブルに挿入している値を見ると、あなたの最高値であるParentIDの値は[6]です。 itms.IDの値に一致するレコードがないため、追加のレコードはリンクされません。

同様の問題は、UserID = 3レコード(問合せの出力を調べて理由を調べる)にあります。

要約 - アイテムをツリー内の別のアイテムにリンクする場合は、アイテム間に特定の一意のリンクが必要です。特定の一意のリンクが存在することを確認する必要があります。単一のデータ値である必要はありませんが、ツリーが分岐するたびに、あるブランチの要素は、そのデータ値に基づいて他のブランチの要素と識別可能に区別されなければなりません。

+0

ありがとうございます。私はこの問題を解決できると思います。ご存知のように、特定のユーザーの下にあるすべてのユーザーを表示するためにこのクエリを使用する必要があります。後で同じクエリを使用してツリーから特定のポイントのツリーを引き出す必要があります。 – Loai

+0

私は異なる表関係で必要なものを達成できると思っていますか、または未使用のテーブルをいくつか取り除くことで実現できますか? – Loai

+0

SQL Serverでツリーを表現する方法はいくつかあります。最も簡単なのは、親ポインタが実際にその親であるレコード、つまりユーザレベルのparentIDを実際に指すようにすることです。もう1つは、ユーザーごとの番号範囲としてツリーを表現することです(たとえば、上記のツリーを使用するなど)。リンクを使って説明するのが簡単になります。 Wikipediaの[Nested Set Model](https://en.wikipedia.org/wiki/Nested_set_model)を参照してください。これは高速で効率的ですが、直感的ではありません。一度それを把握すれば、非常に効率的です。 –

関連する問題