Torna al Thread
USE tempdb;
GO
-- dati di esempio
CREATE TABLE #Originale
(
[IdOrig] [int] NOT NULL,
[Periodicita] [nvarchar](3) NULL,
[Desc1] [nvarchar](250) NULL
);
CREATE TABLE #Replicata
(
[OrigRef] [int] NULL,
[Data] date NULL,
[Desc2] [nvarchar](250) NULL,
[IdReplic] [int] IDENTITY(1,1) NOT NULL
);
INSERT #Originale ([IdOrig], [Periodicita], [Desc1])
VALUES
(101, N'Set', N'scale'),
(102, N'Set', N'temperature'),
(103, N'Set', N'addolcitore'),
(104, N'Men', N'giardini'),
(105, N'Set', N'spese varie'),
(106, N'Set', N'AGGIUNTO!!');
INSERT #Replicata ([OrigRef], [Data], [Desc2])
VALUES
(101, '20150331', N'scale'),
(101, '20150407', N'scale'),
(102, '20150406', N'temperature'),
(102, '20150413', N'temperature'),
(103, '20150425', N'addolcitore'),
(104, '20150310', N'giardini'),
(104, '20150410', N'giardini');
-- data di FINE
DECLARE @EndDate AS date = '20150531';
DECLARE @Id int = 0;
DECLARE @Periodicita char(3) = '';
DECLARE @RefData date;
-- temp table per le massime date per periodicità
DECLARE @MaxDate AS TABLE
(
IdOrig int NOT NULL
, Periodicita char(3) NOT NULL
, UltimaData date NULL
);
-- in questa tabella vado a salvare la data di fine alla quale
-- arrivare nel ciclo di inserimento
-- temp table per le date che andranno inserite
DECLARE @DateDaInserire AS table
(
IdOrig int NOT NULL
, Data date
);
-- in questa tabella vado a mettere le date da inserire,
-- per evitare ulteriori cicli
-- impostazione massime date (raggruppate per il record originale)
INSERT INTO @MaxDate (IdOrig, UltimaData, Periodicita)
SELECT O.IdOrig, MAX(R.Data), O.Periodicita FROM #Replicata R RIGHT JOIN #Originale O ON O.IdOrig = R.OrigRef GROUP BY O.IdOrig, O.Periodicita;
-- questo ciclo continua fino a che esistono record in tabella @MaxDate
WHILE (SELECT COUNT(1) FROM @MaxDate) > 0
BEGIN
-- prendo il primo record dalla tabella @MaxDate
SELECT TOP 1 @Id = IdOrig, @Periodicita = Periodicita, @RefData = UltimaData FROM @MaxDate;
-- caso record NUOVO
IF @RefData IS NULL
BEGIN
INSERT INTO #Replicata (OrigRef, Data, Desc2)
SELECT @Id, GETDATE(), Desc1 FROM #Originale O WHERE O.IdOrig = @Id;
END
ELSE
BEGIN
IF @Periodicita = 'Set'
BEGIN
-- settimanale, ripeto fino a EndDate (viene inserito fino alla prima data dopot @EndDate
WHILE @RefData <= @EndDate
BEGIN
-- il ciclo mi serve solo per aggiungere record nella tabella @DateDaInserire, utile alla fine dello script
SET @RefData = DATEADD(DAY, 7, @RefData);
INSERT INTO @DateDaInserire (IdOrig, Data)
VALUES (@Id, @RefData);
END;
END;
IF @Periodicita = 'Men'
BEGIN
-- mensile, ripeto fino a EndDate (viene inserito fino alla prima data dopot @EndDate
WHILE @RefData <= @EndDate
BEGIN
-- il ciclo mi serve solo per aggiungere record nella tabella @DateDaInserire, utile alla fine dello script
SET @RefData = DATEADD(MONTH, 1, @RefData);
INSERT INTO @DateDaInserire (IdOrig, Data)
VALUES (@Id, @RefData);
END;
END;
END;
-- cancello la riga gestita in modo da ridurre il numero di righe e, alla fine, uscire dal ciclo
DELETE FROM @MaxDate WHERE IdOrig = @Id;
END;
SELECT 'PRIMA', * FROM #Replicata R;
INSERT INTO #Replicata (OrigRef, Data, Desc2)
SELECT
D.IdOrig
, D.Data
, O.Desc1
FROM
@DateDaInserire D
LEFT JOIN #Originale O ON O.IdOrig = D.IdOrig
LEFT JOIN #Replicata R ON R.OrigRef = D.IdOrig AND R.Data = D.Data
WHERE
R.OrigRef IS NULL;
SELECT 'DOPO', * FROM #Replicata R ORDER BY R.OrigRef, R.Data
DROP TABLE #Originale;
GO
DROP TABLE #Replicata;
GO