使用公用表表达式返回父taskID

时间:2012-03-26 08:49:10

标签: c# asp.net sql-server-2008

我需要管理存储在我的数据库中的层次结构数据。但我现在有一个问题。请看我的例子

我有一个名为COMMON.TASK_REL的表

enter image description here

我的第二张桌子叫做Common。任务

enter image description here

如何返回父任务ID?例如,当我选择C_Task_ID 307 时,它将返回父ID 304

这是我的查询

  --Common task SQL modify --
WITH ctLevel
AS
(
SELECT
   C_TASK_ID AS Child
  ,P_Task_ID AS Parent
  ,common_task.TASK_SEQ AS taskOrder
  ,1 AS [Level]
  ,CAST(C_TASK_ID AS VARCHAR(MAX)) AS [Order]
  ,CAST (Replicate('.', 1) + common_task.TASK_NAME AS VARCHAR(25)) AS [Task_Name]
FROM   
       [COMMON.TASK_REL] as common_task_rel, 
       [COMMON.TASK] as common_task
WHERE common_task_rel.C_TASK_ID = common_task.TASK_ID
    and common_task.[TASK_TYPE] = 'B' AND common_task.[MODULE_CODE] = 'LWRPT' 
    AND common_task.[STATUS] <> 'D'
UNION ALL

SELECT 
   C_TASK_ID AS Child
  ,P_Task_ID AS Parent
  ,common_task.TASK_SEQ AS taskOrder
  ,[Level] + 1 AS [Level]
  ,[Order] + '.' + CAST(C_TASK_ID AS VARCHAR(MAX)) AS [Order]
  ,CAST (Replicate('.', [Level] + 1) + common_task.TASK_NAME AS VARCHAR(25)) AS [Task_Name]
FROM   [COMMON.TASK_REL] as common_task_rel
    INNER JOIN ctLevel
       ON ( P_Task_ID = Child ) , [COMMON.TASK] as common_task
WHERE common_task_rel.C_TASK_ID = common_task.TASK_ID
    and common_task.[TASK_TYPE] = 'B' AND common_task.[MODULE_CODE] = 'LWRPT'
    AND common_task.[STATUS] <> 'D'
)

-- Viewing Data
SELECT Child ,Parent ,taskOrder,Level,[Order],Task_Name
FROM   ctLevel  
GROUP BY Child ,Parent ,taskOrder,Level,[Order],Task_Name
order by [Order];
GO

请帮我修改查询。感谢

1 个答案:

答案 0 :(得分:1)

您的查询非常复杂,因此我会为您简化一些建议。

首先是一些测试数据:

DECLARE @TASK_REL TABLE
    (
        ID INT,
        P_TASK_ID INT,
        C_TASK_ID INT
    )
INSERT INTO @TASK_REL
VALUES
    (21,NULL,300),
    (22,300,301),
    (23,300,302),
    (24,300,303),
    (25,NULL,304),
    (26,304,305),
    (27,304,306),
    (28,304,307)

DECLARE @Common TABLE
    (
        TASK_ID INT,
        TASK_Name VARCHAR(100),
        TASK_SEQ INT,
        MODULE_CODE VARCHAR(100),
        STATUS VARCHAR(5),
        TASK_TYPE VARCHAR(5)
    )

INSERT INTO @Common
VALUES
    (300,'Item1',0,'LWRPT','A','B'),
    (301,'Item 1.1',1,'LWRPT','A','B'),
    (302,'Item 1.2',2,'LWRPT','A','B'),
    (303,'Item 1,3',3,'LWRPT','A','B'),
    (304,'Item 2',0,'LWRPT','A','B'),
    (305,'Item 2.1',1,'LWRPT','A','B'),
    (306,'Item 2.2',2,'LWRPT','A','B'),
    (307,'Item 2.3',3,'LWRPT','A','B')

如果您知道每个孩子只有一位父母,您可以轻松地执行此操作:

SELECT
    Common.TASK_Name,
    CommonParent.TASK_Name
FROM
    @Common AS Common
    JOIN @TASK_REL AS TASK_REL
        ON Common.TASK_ID=TASK_REL.C_TASK_ID
    JOIN @Common AS CommonParent
        ON ISNULL(TASK_REL.P_TASK_ID,TASK_REL.C_TASK_ID)=CommonParent.TASK_ID

因为你在表上做了一个递归的cte。我想你可能想要这样的东西:

;WITH CTE(C_TASK_ID,P_TASK_ID,TopParent)
AS
(
    SELECT
        TASK_REL.C_TASK_ID,
        TASK_REL.P_TASK_ID,
        C_TASK_ID AS TopParent
    FROM
        @TASK_REL AS TASK_REL
    WHERE
        TASK_REL.P_TASK_ID IS NULL
    UNION ALL
    SELECT
        TASK_REL.C_TASK_ID,
        TASK_REL.P_TASK_ID,
        CTE.TopParent
    FROM
        @TASK_REL AS TASK_REL
    JOIN CTE
        ON CTE.C_TASK_ID=TASK_REL.P_TASK_ID
)
SELECT
    Common.TASK_Name,
    CommonParent.TASK_Name
FROM
    CTE
    JOIN @Common AS Common
        ON CTE.C_TASK_ID=Common.TASK_ID
    JOIN @Common AS CommonParent
        ON CTE.TopParent=CommonParent.TASK_ID

你在递归部分有很多连接。我认为你应该包括那些依赖于递归的东西,然后在最后加入它。