Torna al Thread
USE tempdb
GO
-- **** Partiamo dalla tua tabella di base **********************************************************
IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'dbo.BOM') AND type in (N'U'))
DROP TABLE dbo.BOM;
CREATE TABLE [dbo].[BOM](
[PN] [varchar](10) NULL,
[CodArt] [varchar](10) NULL,
[Coeff] [float] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'PN1', N'Art1', 1);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'PN1', N'Art2', 2);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'PN1', N'Art3', 1);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'PN1', N'SL1', 2);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'SL1', N'Art4', 1);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'SL1', N'Art5', 1);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'SL1', N'SL2', 1);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'SL2', N'Art6', 1);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'PN2', N'Art1', 1);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'PN2', N'Art8', 2);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'PN2', N'Art3', 1);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'PN2', N'SL1', 1);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'PN2', N'SL3', 1);
INSERT [dbo].[BOM] ([PN], [CodArt], [Coeff]) VALUES (N'SL3', N'Art7', 1);
-- ***** Visualizza Dati **************************************
SELECT * from BOM;
-- ***** Iniziamo *********************************************
DECLARE @intLiv AS int
SET @intLiv = 0
-- creo una tabella di appoggio T2 *******
IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'dbo.T2') AND type in (N'U'))
DROP TABLE dbo.T2;
CREATE TABLE dbo.T2(
[PN] [varchar](10) NULL,
[PN2] [varchar](10) NULL,
[CodArt] [varchar](10) NULL,
[Coeff] [float] NULL,
[Livello] [int] NULL,
[Xxx] [varchar](1) NULL
) ON [PRIMARY]
-- la popolo con i dati della tabella BOM ********
INSERT INTO dbo.T2 ( PN, CodArt, Coeff, Livello ) SELECT dbo.BOM.PN, dbo.BOM.CodArt, dbo.BOM.Coeff, @intLiv AS Li FROM dbo.BOM;
-- Segno con una "x" i record che richiamano la ricorsione
UPDATE dbo.T2 SET dbo.T2.Xxx = N'x' WHERE (dbo.T2.CodArt In (SELECT DISTINCT dbo.BOM.PN FROM dbo.BOM));
-- parte il ciclo sui record segnati con "x"
WHILE (SELECT COUNT(1) AS ccc FROM dbo.T2 WHERE dbo.T2.Xxx = N'x') > 0.5
BEGIN
set @intLiv = @intLiv + 1
-- inserisco i record figli della ricorsione
INSERT INTO dbo.T2 ( dbo.T2.PN, dbo.T2.PN2, dbo.T2.CodArt, dbo.T2.Coeff, dbo.T2.Livello ) SELECT dbo.T2.PN, dbo.BOM.PN, dbo.BOM.CodArt, dbo.BOM.Coeff, @intLiv AS Ll FROM dbo.BOM INNER JOIN dbo.T2 ON dbo.BOM.PN = dbo.T2.CodArt;
-- elimino quanto segnato con "x" in quanto appena sostituito dai suoi figli
DELETE FROM dbo.T2 WHERE dbo.T2.Xxx = N'x';
-- RiSegno con "x" per il prossimo ciclo
UPDATE dbo.T2 SET dbo.T2.Xxx = N'x' WHERE (dbo.T2.CodArt In (SELECT DISTINCT dbo.BOM.PN FROM dbo.BOM));
END
-- ***** visualizzo il risultato *****************************************************
SELECT * FROM dbo.T2 ORDER BY dbo.T2.PN, dbo.T2.PN2, dbo.T2.Livello;