2016-12-14 3 views
1

Ich habe die folgende Tabelle:SQL Server: Eltern-/Kind - Finden tiefste Kind mit Status fehlgeschlagen

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 

Ich habe 2 einzigartigen RUN_ID ist, für die gleichen Serien. Foreach RUN_ID, ich muss Kinder auf der tiefsten Ebene finden, mit dem Status fehlgeschlagen. Aus der obigen Tabelle würde ich finden mag:

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 

Die 6.9 konnte ein gültiges Kind sein, sondern weil es Childs mit dem gescheiterten Status hat, muss sie ausgeschlossen werden. Ich erwarte nicht mehr Level als 4, wie 6.9.4.6.

Es ist möglich, dies in reinem SQL zu lösen? Ich habe versucht, die Ebenenhierarchie zu unterteilen und sie als separate Spalten zu entlarven und mache eine Gruppe mit/CTE, aber ich kann mich nicht darum kümmern.

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 

Update # 1: Anand fragte, ob der Stepname auf einer einzigen Ziffer beginnt. Es funktioniert auf der realen Tabelle, aber ich habe das in meinem aktuellen CTE herausgefiltert, weil auf dieser Ebene kein Fehler auftreten kann.

Update # 2: Ein Paste ist Link für die Erstellung der Tabelle (die CTE fälscht) und INSERT-Anweisungen: http://pastebin.com/7JmP99KP

+0

Gibt es eine Möglichkeit, diese Testdaten in Form eines Skripts verfügbar zu machen? Es wäre einfacher, direkt an der Lösung zu arbeiten, anstatt sich Zeit für den Aufbau der Tabellenstruktur und das Hinzufügen der Beispieldaten zu nehmen. –

+0

Sicher Sache! Gib mir ein oder zwei Minuten. –

+0

F: Kann der Stepname bei 6 anstatt bei 6,9 beginnen? – Anand

Antwort

2

Es wurde ein wenig außer Atem lange das Kind Knoten als Integer-Parsing, ohne es enden als Kopie/Paste speghetti, aber mindestens können Sie die CTE eins nach dem anderen gehen, um zu verstehen, wie ich dorthin komme.

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

Tolles Zeug! Die erste Neufassung deines Skripts scheint meinen CTE zu zerstören, was sehr nett ist! Das Anwenden der benötigten Filter scheint ebenfalls zu funktionieren. Jetzt muss ich nur noch sicherstellen, dass die verschiedenen Szenarien unterstützt werden. Brauchen Sie noch mehr zu graben :) –

+0

Ich Tests haben es nicht geschafft, Ihre Lösung zu brechen, also habe ich Ihre Antwort akzeptiert. Du hast magische Fähigkeiten! :) –

Verwandte Themen