Salve,
si, Sgrubak correttamente indica l'utilizzo di cte ricorsive…
probabilmente scriverei qualche cosa di simile al triviale seguente esempio
USE tempdb;
GO
CREATE TABLE dbo.Relation (
Id int NOT NULL PRIMARY KEY,
Name varchar(10) NOT NULL,
Parent int NULL
);
CREATE TABLE dbo.Data (
Id int NOT NULL PRIMARY KEY IDENTITY,
RelationId int NOT NULL
CONSTRAINT fk_Data$has$Relation
FOREIGN KEY REFERENCES dbo.Relation
(Id),
Value decimal(18,4)
);
GO
INSERT INTO dbo.Relation
VALUES (1, 'A', NULL)
, (11, 'A1', 1)
, (101, 'A2.1', 11), (102, 'A2.2', 11)
, (1001, 'A3.1', 101), (1002, 'A3.2', 101)
, (10001, 'A4', 1001)
, (21, 'B1', 1)
, (201, 'B2', 21)
, (2001, 'B3.1', 201)
, (20001, 'B4.1', 2001), (20002, 'B4.2', 2001);
INSERT dbo.Data
VALUES (1, 1)
, (11, 10)
, (101, 101), (102, 102)
, (1001, 1001), (1002, 1002)
, (10001, 10001)
, (21, 21)
, (201, 201)
, (2001, 2001)
, (20001, 20001), (20002, 20002);
GO
PRINT 'Proiezione gerarchica';
WITH cte AS
(
SELECT CAST(r.Name AS varchar(30)) AS hierPath
, r.Id, r.Name, r.Parent
, 1 AS lvl
, d.Value
FROM dbo.Relation r
JOIN dbo.Data d ON d.RelationId = r.Id
WHERE r.Parent IS NULL
UNION ALL
SELECT CAST(c.hierPath + ' / ' + r.Name AS varchar(30)) as hierPath
, r.Id, r.Name, r.Parent
, c.lvl +1
, d.Value
FROM cte c
INNER JOIN dbo.Relation r ON r.Parent = c.Id
JOIN dbo.Data d ON d.RelationId = r.Id
)
SELECT c.hierPath, c.Id, c.Parent, c.Name, c.lvl
, c.Value + SUM(ISNULL(c2.Value, 0.0)) AS VALUE
FROM cte c
left outer join cte c2 on c2.hierPath <> c.hierPath and left(c2.hierPath, LEN(c.hierPath)) = c.hierPath
GROUP BY c.hierPath, c.Id, c.Parent, c.Name, c.lvl, c.Value
ORDER BY hierPath;
GO
DROP TABLE dbo.Data, dbo.Relation
--<---------
Proiezione gerarchica
hierPath Id Parent Name lvl VALUE
------------------------------ ----------- ----------- ---------- ----------- ------------
A 1 NULL A 1 54444.0000
A / A1 11 1 A1 2 12217.0000
A / A1 / A2.1 101 11 A2.1 3 12105.0000
A / A1 / A2.1 / A3.1 1001 101 A3.1 4 11002.0000
A / A1 / A2.1 / A3.1 / A4 10001 1001 A4 5 10001.0000
A / A1 / A2.1 / A3.2 1002 101 A3.2 4 1002.0000
A / A1 / A2.2 102 11 A2.2 3 102.0000
A / B1 21 1 B1 2 42226.0000
A / B1 / B2 201 21 B2 3 42205.0000
A / B1 / B2 / B3.1 2001 201 B3.1 4 42004.0000
A / B1 / B2 / B3.1 / B4.1 20001 2001 B4.1 5 20001.0000
A / B1 / B2 / B3.1 / B4.2 20002 2001 B4.2 5 20002.0000
Non e' leggerissima….
salutoni romagnoli
–
Andrea