Вернуть родительский taskID с помощью общего табличного выражения - PullRequest
0 голосов
/ 26 марта 2012

Мне нужно управлять хранением данных иерархии в моей базе данных. Но у меня сейчас проблема. Пожалуйста, смотрите мой пример

У меня есть таблица COMMON.TASK_REL

enter image description here

Мой второй стол называется Common. Задача

enter image description here

Как я могу вернуть идентификатор родительской задачи? Например, когда я выбираю C_Task_ID 307 , он возвращает родительский идентификатор, который 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 Ответ

1 голос
/ 26 марта 2012

Ваш запрос довольно сложный, поэтому я упросту некоторые предложения для вас.

Сначала несколько тестовых данных:

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

У вас было много соединений в рекурсивных частях.Я думаю, вы должны включить те, которые зависят от рекурсии, а затем присоединиться к ней в конце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...