我需要管理存储在我的数据库中的层次结构数据。但我现在有一个问题。请看我的例子
我有一个名为COMMON.TASK_REL的表 p>
我的第二张桌子叫做Common。任务
如何返回父任务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
请帮我修改查询。感谢
答案 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
你在递归部分有很多连接。我认为你应该包括那些依赖于递归的东西,然后在最后加入它。