2017-04-25 1 views
-1

Ich versuche, ein CTE inline zu verwenden, wie eine Funktion, aber ich kann keine Funktion erstellen, da ich nur Lesezugriff auf die Datenbank habe. Gibt es einen anderen Weg, dies einfach zu tun?Verwenden Sie eine Ausgabe CTE inline in SQL?

Abfrage:

SELECT SuiteID,ParentSuiteID FROM tbl_Suite; 

Die resultset ist wie:

 
SuiteID ParentSuiteID 
1 0 
4 1 
5 4 
6 4 
7 4 
8 4 
9 4 
10 4 
11 4 

Jetzt habe ich für eine resultset Suche Wo:

 
SuiteID ParentSuiteID Level1ParentID 
1 0     0 
4 1     0 
5 4     1 
6 4     1 
7 4     1 
8 4     1 
9 4     1 
10 4     1 
11 4     1 

MIT DEM CTE unten, ich bin in der Lage zu hole das Level1Parent, wenn ich die SuiteID

übergebe
;WITH HIERARCHY AS 
(select T1.SuiteID,T1.Title,T1.ParentSuiteID, 0 Level FROM tbl_Suite(nolock) T1 
    Where T1.ParentSuiteID = 0 AND T1.PlanID = '404' 
    UNION ALL 
    select T2.SuiteID,T2.Title,T2.ParentSuiteID,Level+1 
    from tbl_Suite(nolock) AS T2 
    INNER JOIN HIERARCHY AS H 
    ON T2.ParentSuiteID = H.SuiteID 
) 

,CTE_A(SuiteID,Title,ParentSuiteID,Level) AS 
(
    select H2.SuiteId, H2.Title, H2.ParentSuiteId, H2.Level 
    from Hierarchy H2 
    --INNER JOIN #X_Temp X 
    --ON H2.SuiteID = X.SuiteID 
    where H2.SuiteID = 10820 
    UNION ALL 
    select H2.SuiteId, H2.Title, H2.ParentSuiteId, H2.Level 
    from Hierarchy H2 JOIN CTE_A On H2.SuiteID = CTE_A.ParentSuiteID 
) 

SELECT SuiteID FROM CTE_A WHERE level = 1 

Meine Frage ist:

A) Wie gebe ich die SuiteID als Inline-Unterabfrage auf der rekursiven CTE-Abfrage? B) Wie kombiniere ich das Resultset wie oben gezeigt?

+2

Sie können einen Blick auf diesen Artikel werfen, bevor Sie weiter Ihre Anfragen mit NOLOCK verstreuen. http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/ –

+0

Was wirklich helfen würde ist, wenn Sie die ddl für Ihre Tabellen und Beispieldaten zusammen mit der gewünschten Ausgabe bereitstellen könnten.Wie es jetzt ist, ist diese erste Abfrage einfach zu lang und verwirrend zu entziffern und es ist mir überhaupt nicht klar, was Sie zu tun versuchen. Dies wäre ein großartiger Ausgangspunkt. http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ –

+0

Hi Sean, in der ersten Abfrage versuche ich das Ergebnisset zu holen was ich beabsichtige Aggregation anzuwenden. Nur die Spalte SuiteID ist für diese Abfrage von Bedeutung, da sie eine Eltern-Kind-Beziehung hat. Daher muss ich für jede SuiteID das Elternelement der zweiten Ebene finden, was das CTE unten tut. Was ich nicht tun kann, ist die Kombination beider Codes, um eine Ausgabe als einzelnes Resultset zu erhalten. – Sharktooth

Antwort

0

Noch nicht ganz sicher, was Sie hier wollen, aber ich denke, Sie haben bereits den Code dafür 99,99999%. Idealerweise würden Sie etwas Verbrauchsmaterial für Daten veröffentlichen. Entlang dieser Linien.

create table #tbl_suite 
(
    SuiteID int 
    , ParentSuiteID int 
) 

insert #tbl_suite 
select 1, 0 union all 
select 4, 1 union all 
select 5, 4 union all 
select 6, 4 union all 
select 7, 4 union all 
select 8, 4 union all 
select 9, 4 union all 
select 10, 4 union all 
select 11, 4 

Dann alles, was jemand tun muss, ist an der Abfrage und nicht das Setup und die Abfrage zu arbeiten. Mit Ihrer Cte ist das ziemlich viel gemacht. Ich musste Title und PlanID entfernen, da sie nicht in den neuen Beispieldaten enthalten sind.

WITH HIERARCHY AS 
( 
    select T1.SuiteID 
     --, T1.Title 
     , T1.ParentSuiteID 
     , 0 Level 
    FROM #tbl_Suite(nolock) T1 
    Where T1.ParentSuiteID = 0 
     --AND T1.PlanID = '404' 
UNION ALL 
    select T2.SuiteID 
     --, T2.Title 
     , T2.ParentSuiteID 
     , Level + 1 
    from #tbl_Suite(nolock) AS T2 
    INNER JOIN HIERARCHY AS H ON T2.ParentSuiteID = H.SuiteID 
) 
select SuiteID 
    , ParentSuiteID 
    , case when Level = 0 then Level else Level -1 end as Level 
from HIERARCHY 
+0

Hallo Sean, ich denke, ich versuche, das Ergebnis als eine neue Spalte in meiner vorherigen Abfrage zu erhalten, da ich das erste Elternteil von jeder Suite bestimmen muss. Nicht sicher, ob ich dieses Recht erkläre. Sie sehen, eine SuiteID kann zu einem Elternelement aufgerollt werden, das wiederum ein Elternelement haben würde, das wiederum rollup würde, bis es root erreicht. Der CTE muss für alle Datensätze aufgerufen werden, um den L1Parent-Datensatz zu ermitteln. Ich verstehe, das muss sehr verwirrend sein. – Sharktooth

+0

Gut, als einige Beispieldaten, die das Problem, die gewünschte Ausgabe und eine Erklärung darstellen. –

0

Ich bin mir nicht sicher, ob ich Ihre Daten verstehe. Ist SuiteId = 1 auf Level 0 oder Level 1?

In Ihrem resultset

SuiteID ParentSuiteID Level1ParentID 
1 0     0 
4 1     0 
5 4     1 
6 4     1 
7 4     1 
8 4     1 
9 4     1 
10 4     1 
11 4     1 

Sie kehren SuiteID = 1 als Level1ParentID für Mitglieder (5, .., 11) suiteid, würde aber die level1parent für Suiteid = 4 nicht suiteid = 1 sein?

Wenn SuiteID = 4 ebenen1 ist, dann sollte Ihr resutl sein:

SuiteID ParentSuiteID Level1ParentID 
1 0     0 
4 1     0 
5 4     4 
6 4     4 
7 4     4 
8 4     4 
9 4     4 
10 4     4 
11 4     4 

Dieses Stück Code gibt das gewünschte Ergebnis. Ich verwende Ihren ursprünglichen CTE für die Hierarchie und zeichne die Level1ParentId in der Hierarchie auf.

Wenn wir mit suiteid = 1 als ebenen1 beginnen dann bekommen wir dieses Ergebnis:

SuiteID ParentSuiteID Level1ParentId 
1 0 0 
4 1 1 
5 4 1 
6 4 1 
7 4 1 
8 4 1 
9 4 1 
10 4 1 
11 4 1 

Wenn wir mit Level beginnen 0, dann erhalten wir:

SuiteID ParentSuiteID Level1ParentId 
1 0 0 
4 1 0 
5 4 4 
6 4 4 
7 4 4 
8 4 4 
9 4 4 
10 4 4 
11 4 4 

Dies ist der Code:

;with tbl_Suite as 
(
select * from (values 
(1 , 0 ,'title 1' ,'404') 
,(4 , 1,'title 4' ,'404') 
,(5 , 4,'title 5' ,'404') 
,(6 , 4,'title 6' ,'404') 
,(7 , 4,'title 7' ,'404') 
,(8 , 4,'title 8' ,'404') 
,(9 , 4,'title 9' ,'404') 
,(10, 4,'title 10','404') 
,(11, 4,'title 11','404') 
) s(SuiteID,ParentSuiteID,Title,PlanId)) 
,HIERARCHY AS 
(select T1.SuiteID,T1.Title,T1.ParentSuiteID, 0 Level,0 Level1ParentId FROM tbl_Suite T1 
    Where T1.ParentSuiteID = 0 AND T1.PlanID = '404' 
    UNION ALL 
    select T2.SuiteID,T2.Title,T2.ParentSuiteID,Level+1 
    ,case when Level=1 then t2.ParentSuiteID else Level1ParentId end 
    from tbl_Suite AS T2 
    INNER JOIN HIERARCHY AS H 
    ON T2.ParentSuiteID = H.SuiteID 
) 
select a.SuiteID,a.ParentSuiteID,b.Level1ParentId from tbl_Suite a 
inner join HIERARCHY b 
on a.SuiteID=b.SuiteID