2016-12-01 2 views
2

Ich versuche zu sehen, ob ich einen Wert aus einer übergeordneten Beziehung innerhalb der gleichen Tabelle erhalten konnte.SQL Server Berechnetes Feld - Daten aus einem übergeordneten Datensatz

Im folgenden Beispiel ist eine Beziehung zu einem übergeordneten Element. RouteName sollte idealerweise ein berechnetes Feld sein, das den routename des direkten Elternteils auswählt (oder den Namen, wenn null).

Auf diese Weise konnte ich eine vollständige Route erstellen, indem nur die direkte übergeordnete ausgewählt und würde Iterating oder CTE'ing über alle Datensätze speichern. Ist das möglich?

+----+------------------+-------------------------------------+-----------+ 
| ID | Name    | RouteName       | Parent_ID | 
+----+------------------+-------------------------------------+-----------+ 
| 1 | Parent   | NULL        |   | 
+----+------------------+-------------------------------------+-----------+ 
| 2 | Child 1   | Parent - Child 1     | 1   | 
+----+------------------+-------------------------------------+-----------+ 
| 3 | Child of Child 1 | Parent - Child 1 - Child of Child 1 | 2   | 
+----+------------------+-------------------------------------+-----------+ 
+1

Wie viele Stufen von _parenthood_ erwarten Sie? Wenn nicht vordefiniert, wäre die Rekursion die einzig vernünftige Lösung. – FDavidov

+0

Ich habe ein Limit von drei - ziemlich genau wie oben. – ExternalUse

+0

Wenn ich den Namen des direkten Elternteils in einem berechneten Feld erhalten könnte, in dem ich den aktuellen Namen verketten könnte, wäre mein Problem gelöst. Pseudo: Wenn Parent_ID nicht Null ist, wählen Sie Parent.Name + '| '+ this.name – ExternalUse

Antwort

1

Sie können eine Funktion für die berechnete Spalte verwenden

drop table MyTable 
drop function dbo.fn_CalculateRouteName 

create table MyTable 
(
    ID int, 
    Name varchar(100), 
    Parent_ID int 
) 
go 

create function dbo.fn_CalculateRouteName(@ID int) 
returns varchar(max) 
begin 
declare @rtn varchar(max); 

with cte (ID, Name) as (
    select Parent_ID, convert(varchar(max), Name) From MyTable where ID = @ID 
    union all 
    select MyTable.Parent_ID, convert(varchar(max), MyTable.Name + ' - ' + cte.Name) 
    from cte 
    inner join MyTable on cte.Id = MyTable.ID 
) 
select @rtn = max(Name) 
from cte 

return @rtn 
end 
go 

alter table MyTable add RouteName AS dbo.fn_CalculateRouteName(ID); 

insert into MyTable(ID, Name, Parent_ID) values(1, 'Parent', null); 
insert into MyTable(ID, Name, Parent_ID) values(2, 'Child 1', 1); 
insert into MyTable(ID, Name, Parent_ID) values(3, 'Child of Child 1', 2); 

select * from MyTable 
+0

Danke James, ich werde es versuchen. Wenn ich diese Spalte behalte, ist der Leistungsaufwand vielleicht nicht so hoch, denke ich? Ich denke immer noch über die Auslöserlösung nach, die FDavidov vorgeschlagen hat, aber ich werde versuchen, darüber zu berichten. Ich werde die Antwort nach dem Test akzeptieren, wenn das in Ordnung ist. – ExternalUse

Verwandte Themen