我有下表:
STEPID|RUN_ID|SERIAL |PARENT|STEPNAME |STATUS
171730| 3101|0103107|171696|6.9 - Load Program YXZ |Failed
171740| 3101|0103107|171730|6.9.5 - Step Test. Program YXZ Error Code |Failed
171741| 3101|0103107|171730|6.9.6 - Step Test. Program YXZ - Part 1 |Failed
171742| 3101|0103107|171730|6.9.7 - Step Test. Program YXZ - Part 2 |Failed
171743| 3101|0103107|171730|6.9.8 - Step Test. Program YXZ - Part 3 |Failed
171744| 3101|0103107|171730|6.9.9 - Step Test. Program YXZ - Part 4 |Failed
171745| 3101|0103107|171730|6.9.10 - Step Test. Program YXZ - Part 5 |Failed
171785| 3102|0103107|171751|6.9 - Load Program YXZ |Failed
171788| 3102|0103107|171785|6.9.4 - Run Test - Monitor |Failed
171789| 3102|0103107|171788|6.9.4.1 - Step Test. Program YXZ - Part 11|Failed
171790| 3102|0103107|171788|6.9.4.2 - Step Test. Program YXZ - Part 12|Failed
171791| 3102|0103107|171788|6.9.4.3 - Step Test. Program YXZ - Part 13|Failed
171792| 3102|0103107|171788|6.9.4.4 - Step Test. Program YXZ - Part 14|Failed
171793| 3102|0103107|171788|6.9.4.5 - Step Test. Program YXZ - Part 15|Failed
171794| 3102|0103107|171788|6.9.4.6 - Step Test. Program YXZ - Part 16|Failed
171795| 3102|0103107|171785|6.9.5 - Step Test. Program YXZ Error Code |Failed
171796| 3102|0103107|171785|6.9.6 - Step Test. Program YXZ - Part 1 |Failed
171797| 3102|0103107|171785|6.9.7 - Step Test. Program YXZ - Part 2 |Failed
171798| 3102|0103107|171785|6.9.8 - Step Test. Program YXZ - Part 3 |Failed
171799| 3102|0103107|171785|6.9.9 - Step Test. Program YXZ - Part 4 |Failed
171800| 3102|0103107|171785|6.9.10 - Step Test. Program YXZ - Part 5 |Failed
对于同一个序列,我有2个唯一的RUN_ID#。 Foreach RUN_ID,我需要找到最深层次的孩子,状态失败。从上表我想找到:
STEPID|RUN_ID|SERIAL |PARENT|STEPNAME |STATUS
171745| 3101|0103107|171730|6.9.10 - Step Test. Program YXZ - Part 5 |Failed
171794| 3102|0103107|171788|6.9.4.6 - Step Test. Program YXZ - Part 16|Failed
171800| 3102|0103107|171785|6.9.10 - Step Test. Program YXZ - Part 5 |Failed
6.9可能是一个有效的孩子,但因为它有状态失败的孩子,所以需要将其排除在外。我不希望等级超过4,如6.9.4.6。
有可能在纯SQL中解决这个问题吗?我试图对级别层次结构进行子串,并将其作为单独的列公开,并按/ CTE进行一些分组,但我无法理解它。
STEPID|RUN_ID|SERIAL |PARENT|Level1|Level2|Level3|Level4|STATUS
171785| 3102|0103107|171751| 6| 9| NULL| NULL|Failed
171788| 3102|0103107|171785| 6| 9| 4| NULL|Failed
171789| 3102|0103107|171788| 6| 9| 4| 1|Failed
171790| 3102|0103107|171788| 6| 9| 4| 2|Failed
更新#1: Anand询问步骤名是否以单个数字开头。它在真实的桌子上,但我已经在我当前的CTE中过滤掉了,因为在该级别上不会发生错误。
更新#2: 用于创建表(伪造CTE)和插入语句的粘贴bin链接:http://pastebin.com/7JmP99KP
答案 0 :(得分:2)
它有点长时间将子节点解析为一个整数而不是最终复制/粘贴speghetti,但至少你可以逐个走CTE以了解我是如何到达那里的。
WITH
StepWithTrimmedName AS
(
SELECT
*,
SUBSTRING(s.STEPNAME, 1, CHARINDEX(' - ', s.STEPNAME) - 1) AS TrimmedName
FROM
dbo.Temp_Steps s
),
StepWithPeriod AS
(
SELECT
*,
CHARINDEX('.', REVERSE(s.TrimmedName)) AS Period
FROM
StepWithTrimmedName s
),
StepWithCharacterLength AS
(
SELECT
*,
CASE
WHEN s.Period = 0 THEN 1
ELSE s.Period - 1
END AS CharacterLength
FROM
StepWithPeriod s
),
StepWithStartPosition AS
(
SELECT
*,
LEN(s.TrimmedName) - s.CharacterLength + 1 AS StartPosition
FROM
StepWithCharacterLength s
),
StepWithRowNumber AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY s.PARENT ORDER BY
CAST(SUBSTRING(s.TrimmedName, s.StartPosition, s.CharacterLength) AS INT) DESC) AS RowNum
FROM
StepWithStartPosition s
WHERE
s.[Status] = 'Failed'
)
SELECT
*
FROM
StepWithRowNumber s
WHERE
s.RowNum = 1 AND
NOT EXISTS
(
SELECT *
FROM
StepWithRowNumber c
WHERE
c.PARENT = s.StepId
)
ORDER BY
S.SERIAL,
s.RUN_ID,
s.PARENT,
s.RowNum;