来自上一个子记录的公用表表达式

时间:2013-07-23 22:37:18

标签: sql-server-2008 parent-child hierarchy common-table-expression

您好我有一个站点地图表和一个等级表。

    USE [EB_NEW]
GO
/****** Object:  Table [dbo].[COMMON.SITEMAP]    Script Date: 07/24/2013 06:13:51 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[COMMON.SITEMAP](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [P_ID] [int] NULL,
    [C_ID] [int] NULL,
    [TYPE] [varchar](50) NULL,
    [TITLE] [varchar](50) NULL,
    [TASK_URL_ID] [bigint] NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[COMMON.SITEMAP] ON
INSERT [dbo].[COMMON.SITEMAP] ([ID], [P_ID], [C_ID], [TYPE], [TITLE], [TASK_URL_ID]) VALUES (2, NULL, 2, N'EB', N'Employee Benefit', NULL)
INSERT [dbo].[COMMON.SITEMAP] ([ID], [P_ID], [C_ID], [TYPE], [TITLE], [TASK_URL_ID]) VALUES (3, 2, 3, N'Company', N'Company Listing', 175)
INSERT [dbo].[COMMON.SITEMAP] ([ID], [P_ID], [C_ID], [TYPE], [TITLE], [TASK_URL_ID]) VALUES (4, 3, 4, N'Company', N'Company Profile Setup', 176)
INSERT [dbo].[COMMON.SITEMAP] ([ID], [P_ID], [C_ID], [TYPE], [TITLE], [TASK_URL_ID]) VALUES (5, 4, 5, N'Company', N'Company Policy Setup', 191)
INSERT [dbo].[COMMON.SITEMAP] ([ID], [P_ID], [C_ID], [TYPE], [TITLE], [TASK_URL_ID]) VALUES (6, 4, 6, N'Company', N'Employee Profile Setup', 178)
INSERT [dbo].[COMMON.SITEMAP] ([ID], [P_ID], [C_ID], [TYPE], [TITLE], [TASK_URL_ID]) VALUES (7, 5, 7, N'Company', N'Company Policy Setup 2', NULL)
INSERT [dbo].[COMMON.SITEMAP] ([ID], [P_ID], [C_ID], [TYPE], [TITLE], [TASK_URL_ID]) VALUES (8, 6, 8, N'Company', N'Employee Profile Setup 2', NULL)
SET IDENTITY_INSERT [dbo].[COMMON.SITEMAP] OFF

结果

ID  P_ID       C_ID     TYPE    TITLE                       TASK_URL_ID
2   NULL         2        EB    Employee Benefit              NULL
3   2            3    Company   Company Listing               175
4   3            4    Company   Company Profile Setup         176
5   4            5    Company   Company Policy Setup          191
6   4            6    Company   Employee Profile Setup        178
7   5            7    Company   Company Policy Setup 2        NULL
8   6            8    Company   Employee Profile Setup 2      NULL

我使用公用表表达式来确定层次结构数据

WITH ctLevel
                AS
                (
                    SELECT
                        C_ID                                                                AS Child
                        ,P_ID                                                               AS Parent
                        ,1                                                                  AS [Level]
                        ,TASK_URL_ID                                                        As taskUrl_ID   
                        ,TITLE                                                              As title
                        ,TYPE                                                               As Type     
                        ,ID                                                                 As ID                                                       

                    FROM   
                       [COMMON.SITEMAP] as common_sitemap

                    WHERE  
                        P_ID is null and common_sitemap.TYPE ='EB'


                    UNION ALL

                    SELECT 
                        C_ID                                                                    AS Child
                        ,P_ID                                                                   AS Parent
                        ,[Level] + 1                                                            AS [Level]
                        ,TASK_URL_ID                                                            As cTaskUrl_ID
                        ,common_sitemap.TITLE                                                   As ctitle
                        ,common_sitemap.TYPE                                                    As cType    
                        ,common_sitemap.ID                                                      As cID                                                                              

                    FROM   
                        [COMMON.SITEMAP]as common_sitemap


                    inner JOIN 
                        ctLevel
                    ON 
                        ( 
                        P_ID = Child 

                        )

                    WHERE  
                            common_sitemap.P_ID is not null 



                    )

                  SELECT  DISTINCT [Parent] ,[Child], ctLevel.title,ctLevel.Type,

                  ctLevel.taskUrl_ID,
                   ctLevel.Level,
                    common_task_url.TASK_URL
                    FROM   ctLevel 
                    left join   
                    [COMMON.TASK_URL]as common_task_url 
                    on
                     ctLevel.taskUrl_ID = common_task_url.TASK_URL_ID


                    order by Level 

结果

Parent      Child       title                                              Type                                               taskUrl_ID           Level       TASK_URL
----------- ----------- -------------------------------------------------- -------------------------------------------------- -------------------- ----------- -------------------
NULL        2           Employee Benefit                                   EB                                                 NULL                 1           NULL
2           3           Company Listing                                    Company                                            175                  2           ~/Module/EB/Company/CompanyList.aspx
3           4           Company Profile Setup                              Company                                            176                  3           ~/Module/EB/Company/CompanyDetail.aspx
4           5           Company Policy Setup                               Company                                            191                  4           ~/Module/EB/Company/CompanyPolicy.aspx
4           6           Employee Profile Setup                             Company                                            178                  4           ~/Module/EB/Employee/EmployeeDetail.aspx
5           7           Company Policy Setup 2                             Company                                            NULL                 5           NULL
6           8           Employee Profile Setup 2                           Company    

所以我的问题是,是否有可能从最后一个子记录中获取整个相关的层次结构记录。例如 儿童记录 7

结果会得到

Parent      Child       title                                              Type                                               taskUrl_ID           Level       TASK_URL
----------- ----------- -------------------------------------------------- -------------------------------------------------- -------------------- ----------- -----------------------
NULL        2           Employee Benefit                                   EB                                                 NULL                 1           NULL
2           3           Company Listing                                    Company                                            175                  2           ~/Module/EB/Company/CompanyList.aspx
3           4           Company Profile Setup                              Company                                            176                  3           ~/Module/EB/Company/CompanyDetail.aspx
4           5           Company Policy Setup                               Company                                            191                  4           ~/Module/EB/Company/CompanyPolicy.aspx
5           7           Company Policy Setup 2                             Company                                            NULL                 5           NULL

但如果儿童记录 8

Parent      Child       title                                              Type                                               taskUrl_ID           Level       TASK_URL
----------- ----------- -------------------------------------------------- -------------------------------------------------- -------------------- ----------- -----------------------
NULL        2           Employee Benefit                                   EB                                                 NULL                 1           NULL
2           3           Company Listing                                    Company                                            175                  2           ~/Module/EB/Company/CompanyList.aspx
3           4           Company Profile Setup                              Company                                            176                  3           ~/Module/EB/Company/CompanyDetail.aspx
4           6           Employee Profile Setup                             Company                                            178                  4           ~/Module/EB/Employee/EmployeeDetail.aspx
6           8           Employee Profile Setup 2                           Company                                            NULL                 5           NULL

任何灵魂人物?感谢

1 个答案:

答案 0 :(得分:0)

有可能。它与您遍历树的方式非常相似。我做了一个小例子:http://sqlfiddle.com/#!3/842ce/13

declare @childID int = 7;

with tree as (
    select parent, id from T where parent is null
  union all
    select t.parent, t.id from T
    join tree on T.parent = tree.id
), bottomUp as (
    select parent, id from tree where id = @childID
  union all
    select t.parent, t.id from tree t
    join bottomUp on bottomUp.parent = t.id
)
select * from bottomUp
order by id asc

在这里,我正在穿越我走过的树。但是,如果您不想使用,则不必使用第一个树。在bottomUp中将树更改为T,它仍然有效。如果你已经有修剪树的逻辑,你可以保留它。如果您没有任何逻辑,那么如果您只有第二个没有第一个CTE,则速度会更快。