Ниже приведен весь запрос (включая базовый код сверху). В моем чате с крокодилом результаты совпадают именно так, как запрошено. Это решение не имеет предшествующей рекурсии, поскольку Гаррет указал, что оно не является необходимым. Я оставил рекурсивное решение ниже на случай, если проблема станет более сложной и потребует рекурсии. Оба решения должны работать, хотя
create table #customer (
id int not null primary key identity,
cust_no varchar(12),
meter_no varchar(10),
startdate smalldatetime,
enddate smalldatetime,
terminateDate smalldatetime,
oldid int null
)
insert into #customer values('AA111222','1111','2008-01-01', '2009-03-01','2008-04-15',null)
insert into #customer values('AA111222','1111','2008-01-01', '2009-05-01',null,null)
insert into #customer values('AA111222','1111','2008-03-01', '2008-12-01',null,null)
insert into #customer values('AA111222','1111','2009-05-01', '2009-07-01',null,null)
insert into #customer values('AA111222','1111','2009-08-01', '2009-11-01',null,null)
insert into #customer values('AA111222','1111','2010-01-01', '2010-04-01',null,null)
insert into #customer values('AA111222','1111','2010-07-01', '2011-07-01',null,null)
insert into #customer values('AA111222','1111','2011-03-01', '2011-07-01',null,null)
insert into #customer values('AA111222','1111','2011-07-01', '2012-07-01',null,null)
insert into #customer values('BB111222','1112','2011-03-01', '2011-07-01',null,null)
insert into #customer values('BB111222','1112','2011-07-01', '2012-07-01',null,null)
insert into #customer values('CC111222','1113','2011-09-01', '2012-07-01',null,null)
insert into #customer values('CC111222','1113','2011-03-01', '2011-07-01',null,null)
insert into #customer values('CC111222','1113','2011-07-01', '2012-07-01',null,null)
; WITH RankingCTE (id, cust_no, meter_no, startdate, enddate, terminatedate,
oldid, CustomerRank)
AS
(
SELECT *, ROW_NUMBER() OVER
(PARTITION BY cust_no, meter_no ORDER BY startdate, terminatedate)
AS CustomerRank
FROM #customer
)
UPDATE #customer
SET oldid = OrganizedCTE.OldID
FROM #customer
JOIN
( SELECT BaseCTE.ID, NextInRankCTE.ID AS OldID
FROM RankingCTE AS BaseCTE
LEFT JOIN RankingCTE AS NextInRankCTE
ON NextInRankCTE.Meter_No = BaseCTE.Meter_No
AND NextInRankCTE.Cust_No = BaseCTE.Cust_no
AND BaseCTE.CustomerRank = NextInRankCTE.CustomerRank + 1
) AS OrganizedCTE
ON OrganizedCTE.ID = #customer.ID
;
SELECT * FROM #customer
Это рекурсивное решение, с полным решением также:
create table #customer (
id int not null primary key identity,
cust_no varchar(12),
meter_no varchar(10),
startdate smalldatetime,
enddate smalldatetime,
terminateDate smalldatetime,
oldid int null
)
insert into #customer values('AA111222','1111','2008-01-01', '2009-03-01','2008-04-15',null)
insert into #customer values('AA111222','1111','2008-01-01', '2009-05-01',null,null)
insert into #customer values('AA111222','1111','2008-03-01', '2008-12-01',null,null)
insert into #customer values('AA111222','1111','2009-05-01', '2009-07-01',null,null)
insert into #customer values('AA111222','1111','2009-08-01', '2009-11-01',null,null)
insert into #customer values('AA111222','1111','2010-01-01', '2010-04-01',null,null)
insert into #customer values('AA111222','1111','2010-07-01', '2011-07-01',null,null)
insert into #customer values('AA111222','1111','2011-03-01', '2011-07-01',null,null)
insert into #customer values('AA111222','1111','2011-07-01', '2012-07-01',null,null)
insert into #customer values('BB111222','1112','2011-03-01', '2011-07-01',null,null)
insert into #customer values('BB111222','1112','2011-07-01', '2012-07-01',null,null)
insert into #customer values('CC111222','1113','2011-09-01', '2012-07-01',null,null)
insert into #customer values('CC111222','1113','2011-03-01', '2011-07-01',null,null)
insert into #customer values('CC111222','1113','2011-07-01', '2012-07-01',null,null)
SELECT *, ROW_NUMBER() OVER
(PARTITION BY cust_no, meter_no ORDER BY startdate ASC, terminatedate ASC)
AS CustomerRank
INTO #RankingTable
FROM #customer
;WITH SortingCTE(id, cust_no, meter_no, startdate, enddate, terminatedate,
oldid, CustomerRank)
AS
(
-- Anchor member definition
SELECT id, cust_no, meter_no, startdate, enddate, terminatedate,
null as oldid, CustomerRank
FROM #RankingTable
WHERE CustomerRank = 1
UNION ALL
-- Recursive member definition
SELECT #RankingTable.id, #RankingTable.cust_no, #RankingTable.meter_no,
#RankingTable.startdate, #RankingTable.enddate,
#RankingTable.terminatedate, SortingCTE.id as oldid,
#RankingTable.CustomerRank
FROM #RankingTable
JOIN SortingCTE
ON SortingCTE.cust_no = #RankingTable.cust_no
AND SortingCTE.meter_no = #RankingTable.meter_no
AND SortingCTE.CustomerRank+1 = #RankingTable.CustomerRank
)
-- Statement that executes the CTE
UPDATE #customer
SET oldid = SortingCTE.oldid
FROM SortingCTE
JOIN #customer on #customer.id = SortingCTE.id
;
SELECT * FROM #customer