Annahmen:
CategoryId ist ein Primärschlüssel.
Wenn die Beschreibung auf Zeilenebene null ist, sehen Sie sich die übergeordnete Zeile an. Wenn die übergeordnete Zeile null Beschreibung hat, sehen Sie sich das übergeordnete Element an. Mit anderen Worten: Verwenden Sie die erste Nicht-Null-Beschreibung von Vorfahren.
Wenn Zeilenebene Beschreibung null ist, und kein Vorfahr existiert mit nicht null Beschreibung, ist allgemeine Beschreibung null
einrichten Beispieltabelle und Testdaten.
create table #SO (CategoryID int primary key
, ParentCategoryID int Null
, Name varchar(255) not null
, Description varchar(MAX) Null
)
insert into #SO (CategoryID, ParentCategoryID, Name, Description)
values (1, null, 'Top 1', 'Top 1 Description')
, (2, null, 'Top 2', 'Top 2 Description')
, (3, null, 'Top 3', null)
, (11, 1, 'Child 11', 'Child 11 Description')
, (12, 1, 'Child 12', null)
, (21, 2, 'Child 21', null)
, (211, 21, 'Child 211', null)
, (2111, 211, 'Child 2111', null)
, (2112, 211, 'Child 2112', 'Child 2112 Description')
, (31, 3, 'Child 31', 'Child 31 Description')
, (32, 3, 'Child 32', null)
Verwendung eines rekursiven CTE. Beachten Sie, dass der Baum nach oben geht.Wir beginnen mit allen Zeilen und sehen dann nach Bedarf die Eltern an, anstatt die normale Baummanipulation zu machen, indem wir ganz oben im Baum beginnen und arbeiten.
; with Description (BaseCategoryId
, CurrentParentCategoryId
, CurrentDescription
, CurrentLevel)
as
(-- Anchor -- Start with all rows in the table.
select CategoryId as BaseCategoryId
, ParentCategoryId as CurrentParentCategoryId
, Description as CurrentDescription
, 0 as CurrentLevel
from #SO -- Recursive -- We are walking up the tree from all nodes,
-- We only continue up the tree when we do not have a description yet.
union all
select D.BaseCategoryId
, so.ParentCategoryId
, so.Description
, D.CurrentLevel + 1
from #SO so
inner join Description D
on D.CurrentParentCategoryId = so.CategoryId
and D.CurrentDescription is null)
select DL.BaseCategoryId as CategoryId
, DL.CurrentDescription as UltimateDescription
-- Now self outer join with the CTE every step of the walk
-- for each BaseCategoryId, and then filter all but the top
-- level. (Level is measured as distance from base.)
from Description as DL
left outer join Description as DR
on DL.BaseCategoryId = DR.BaseCategoryId
and DL.CurrentLevel < DR.CurrentLevel
where DR.BaseCategoryId is null
order by DL.BaseCategoryId
Die Ausgabe ist eine Zuordnung von CategoryId zur endgültigen Beschreibung.
In Bezug auf die Wiederverwendung würde ich das obige eine Sicht machen.
Welche Marke von SQL verwenden Sie? – Talljoe
Sieht wie vielleicht SQLServer von der varchar (MAX) -Syntax aus? – Plasmer
MsSql, tut mir leid, das war nur Pseudocode für das, wie die Tabelle aussieht. Glaubt jemand, dass eine Funktion verwendet werden könnte, um dies zu erreichen? Ich mag das "mit" Zeug. Hat MySql 'mit'? –