2016-12-14 5 views
1

を失敗した私は、次のテーブルがあります。SQL Serverの:親/子 - ステータスで最も深い子を探す

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は有効な子かもしれないが、それが失敗した状態でのチャイルズを持っているので、それは除外される必要があります。私は6.9.4.6のように、4以上のレベルは期待していません。

純粋な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:STEPNAMEは一桁に開始した場合 アナンドは尋ねました。それは実際のテーブルではありますが、そのレベルではエラーが発生しないため、現在のCTEでフィルタリングしています。

更新#2: (CTEを偽造)テーブルを作成するためのペーストビンリンクや文を挿入します。http://pastebin.com/7JmP99KP

+0

このテストデータをスクリプトの形式で公開する方法はありますか?テーブル構造を構築してサンプルデータを追加するのではなく、ソリューションを直接操作する方が簡単です。 –

+0

確かに!私に1,2分を与えてください。 –

+0

Q:ステップ名は6.9ではなく6で始めることができますか? – Anand

答えて

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; 
+0

素晴らしいもの!あなたのスクリプトの最初の書き換えはCTEを殺しているようですが、これはとてもいいです!必要なフィルタを適用することも同様に機能するようです。今は、さまざまなシナリオがサポートされていることを確認するだけです。より多くの掘り下げを行う必要があります:) –

+0

私のテストはあなたの解決策を破ることができなかったので、私はあなたの答えを受け入れました。あなたは魔法のスキルを持っています! :) –

関連する問題