簡體   English   中英

不同表中的樹結構

[英]tree structure in different tables

我有四個桌子,

  • Level1(id,名稱,idFather,LevelFather)
  • Level2(id,名稱,idFather,LevelFather)
  • Level3(id,名稱,idFather,LevelFather)
  • Level4(id,名稱,idFather,LevelFather)

此邏輯允許構建一棵樹,其中葉子是Level4中的項目,而他的父親可以選擇Level 1、2或3。以同樣的方式,Level3中的項目可以擁有2 o 1的父親。

是否有任何查詢要獲取給定ID和級別的以下樹,直到給定級別?

例如,是否有下一個數據:

級別1-001,GroupEnterprise1,001,1

級別2-001-1,Enterprise1、001、1

級別2-001-2,Enterprise2,001、1

3級-002-1,Enterprise3、001-1、2

4級-003-1,辦公室1,001-1,3

級別4-003-2,辦公室2,001-2,3

級別4-003-3,辦公室3,001-2,3

4級-003-4,辦公室4,001-1,3

我可以咨詢所有屬於GroupEnterprise1組的辦公室(第4級中的項目),它們是GroupEnterprise1組的女兒,孫女和曾孫女,或者是Enterprise3的女兒辦公室,或者是GroupEnterprise1的女兒的企業。

查詢的參數是Id,Level和Level,直到我希望構建樹為止。

我不確定我是否完全理解您要做什么。 如果需要層次結構,則應使用一個名為“級別”的表,並將所有級別信息存儲在該表中。 您不需要4個表。 您可以執行自聯接以輕松返回父信息。

問題在於,為了遍歷整個鏈,您可能必須使用某種循環。 通常在SQL語句中應避免這種情況,因為查詢優化器將必須為循環的每次迭代生成執行計划(效率低下)。 可以僅使用SQL進行處理,但我建議提取一個包含所有信息的表,並使用不適合基於集合的操作的非SQL編程語言對其進行解析。

以下是對所有4個級別使用單個表格的一些示例代碼。 一旦在表中構建了樹,您只需要遍歷FOR循環以按需要顯示它。

--Creates Temp table (This table will expire upon connection close)
CREATE TABLE [#Levels] ([id] INT, [name] NVARCHAR(256), [level] INT, [idFather] INT);

--Populate Temp table with some sample data
INSERT INTO #Levels VALUES (1,'AbsoluteParent',1,null)
INSERT INTO #Levels VALUES (2,'ChildItem1',2,1)
INSERT INTO #Levels VALUES (3,'ChildItem2',2,1)
INSERT INTO #Levels VALUES (4,'GrandChild',3,2)

--Display populated table
SELECT * FROM [#Levels]

--Create 2 instances of our Temp table and join (id > idFather) so that we can return information about the parent table.  
SELECT [T1].[name] AS 'Name'
    , [T2].[name] AS 'Parent Name'
FROM [#Levels] AS T1
    LEFT JOIN [#Levels] T2 ON [T1].[idFather] = [T2].[id]

--We can even link another instance of our Temp table and give information about grandparents! 
SELECT [T1].[name] AS 'Name'
    , [T2].[name] AS 'Parent Name'
    , [T3].[name] AS 'Grand Parent Name' 
FROM [#Levels] AS T1
    LEFT JOIN [#Levels] T2 ON [T1].[idFather] = [T2].[id]
    LEFT JOIN [#Levels] T3 ON [T2].[idFather] = [T3].[id]

也許您正在尋找的是遞歸公用表表達式,該表達式將輸出反饋到函數中以遞歸顯示所有子項。 這是一個Microsoft示例: https : //technet.microsoft.com/zh-cn/library/ms186243(v= sql.105) .aspx

我簡化了微軟的例子:

 -- Create a temp Employee table.
CREATE TABLE #MyEmployees
(
    EmployeeID smallint NOT NULL,
    FirstName nvarchar(30)  NOT NULL,
    LastName  nvarchar(40) NOT NULL,
    Title nvarchar(50) NOT NULL,
    ManagerID int NULL, 
);
-- Populate the table with values.
INSERT INTO #MyEmployees VALUES 
 (1, N'Ken', N'Sánchez', N'Chief Executive Officer',NULL)
,(273, N'Brian', N'Welcker', N'Vice President of Sales',1)
,(274, N'Stephen', N'Jiang', N'North American Sales Manager',273)
,(275, N'Michael', N'Blythe', N'Sales Representative',274)
,(276, N'Linda', N'Mitchell', N'Sales Representative',274)
,(285, N'Syed', N'Abbas', N'Pacific Sales Manager',273)
,(286, N'Lynn', N'Tsoflias', N'Sales Representative',285)
,(16,  N'David',N'Bradley', N'Marketing Manager',273)
,(23,  N'Mary', N'Gibson', N'Marketing Specialist',16);


WITH DirectReports (ManagerID, EmployeeID, Title, Level)
AS
(
    SELECT e.ManagerID, e.EmployeeID, e.Title, 0 AS Level
    FROM #MyEmployees AS e
    WHERE e.ManagerID is null

    UNION ALL

    SELECT e.ManagerID, e.EmployeeID, e.Title, d.Level + 1
    FROM #MyEmployees AS e
    INNER JOIN DirectReports AS d
    ON e.ManagerID = d.EmployeeID
)
SELECT ManagerID, EmployeeID, Title, Level
FROM DirectReports

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM