我问了一个非常相似的问题here,但我现在需要更多提前查询。情况是,我们有大约20,000个客户记录。客户可以续订,我们只需为其创建新记录。没有确切的追溯记录实际更新的记录。现在我们添加了old ID
字段,并且我希望使用确切的旧记录填充它。现在,如果它被更新一次,那已经处理了我的旧问题,我可以做到。问题是如果记录被更新了3次或更多次,我必须找到最旧记录跳到最新记录的确切逻辑。为此,我们没有设置规则,但通常我遵循customer start date
(并且ID本身会抛出一些记录首先出现的光),现在将使用customer start date
来填充所有记录。我在这里包含了一个测试用例
create table #customer (
id int not null primary key identity,
cust_no varchar(12),
meter_no varchar(10),
startdate smalldatetime,
enddate smalldatetime,
oldid int null
)
insert into #customer values('AA111222','1111','2008-01-01', '2008-03-01',null)
insert into #customer values('AA111222','1111','2009-02-01', '2009-05-01',null)
insert into #customer values('AA111222','1111','2008-03-01', '2008-12-01',null)
insert into #customer values('AA111222','1111','2009-05-01', '2009-07-01',null)
insert into #customer values('AA111222','1111','2009-08-01', '2009-11-01',null)
insert into #customer values('AA111222','1111','2010-01-01', '2010-04-01',null)
insert into #customer values('AA111222','1111','2010-07-01', '2011-07-01',null)
insert into #customer values('AA111222','1111','2011-03-01', '2011-07-01',null)
insert into #customer values('AA111222','1111','2011-07-01', '2012-07-01',null)
-- I want this result in the last column
id cust_no meter_no startdate enddate oldid
---- ------------ ---------- -------------- -------------- -------
1 AA111222 1111 2008-01-01 2008-03-01 base
2 AA111222 1111 2009-02-01 2009-05-01 3
3 AA111222 1111 2008-03-01 2008-12-01 1
4 AA111222 1111 2009-05-01 2009-07-01 2
5 AA111222 1111 2009-08-01 2009-11-01 4
6 AA111222 1111 2010-01-01 2010-04-01 5
7 AA111222 1111 2010-07-01 2011-07-01 6
8 AA111222 1111 2011-03-01 2011-07-01 7
9 AA111222 1111 2011-07-01 2012-07-01 8
请注意,不同的方式是值得赞赏的,所以我也可以学到一些东西。到目前为止,我已经看过CTE,Join,Cursor,但如果我能在第一时间做到这一点,那么我需要一些时间来完成它。
答案 0 :(得分:1)
我知道,你可能不喜欢我的回答,但我会更改数据库的设计并添加2个表。 它可以提高数据库中的速度并减少冗余数据。
Table 1
Contract
contract_id | startdate | meter_no | cust_no
Table 2
Contract_detail
contract_id | startdate | enddate
以下是使用旧数据填充表格的方法: 我假设,每个客户只有一份合同,如果他在客户表中有多个条目,那么他会更新。
如果您将合约中的列contract_id定义为autovalue,请尝试以下操作。
This inserts for every cust_no and meter_no combination one entry.
Insert into contract
(cust_no, startdate, enddate, meter_no)
Select distinct cust_no
,Min (startdate)
,Max (enddate)
,meter_no
from customer
Group by cust_no, meter_no
GO
Insert into contract_detail
(contract_id, cust_no, startdate, enddate)
Select co.contract_id
,co.cust_no
,cu.startdate
,cu.enddate
from contract co
inner join customer cu on co.cust_no = cu.cust_no
and co.meter_no = cu.meter_no
GO
答案 1 :(得分:1)
第二个答案: 您可以使用以下语句更新old_id列!
Update #customer
SET oldid =
(Select TOP 1 c_old.id from #customer c_old
where c_old.enddate <= #customer.startdate
and c_old.cust_no = #customer.cust_no
and c_old.meter_no = #customer.meter_no
and c_old.enddate =
(
SELECT max(c.enddate) FROM #customer c
where c_old.cust_no = c.cust_no
and c_old.meter_no = c.meter_no
and #customer.startdate >= c.enddate
)
)
from #customer
go
答案 2 :(得分:0)
我使用的实际查询完美无缺。只有在@chris回答之后才有可能。它是他的修改版。
Update #customer
SET oldid =
(Select TOP 1 c_old.id from #customer c_old
where c_old.startdate < #customer.startdate
and c_old.cust_no = #customer.cust_no
and c_old.meter_no = #customer.meter_no
and c_old.id != #customer.id
order by c_old.startdate desc
)
from #customer