2012-02-03 9 views
1

私は非常によく似た質問をしましたhereしかし、私はより多くの事前照会が今必要です。状況は、私たちは約2万の顧客レコードを持っています。顧客は更新して、新しいレコードを作成するだけです。実際にどのレコードが更新されたかを正確にトレースすることはできません。今度はold IDフィールドを追加しました。正確な古いレコードをフィールドに追加します。今度はそれが一度更新されれば、それは私の古い質問に気を配り、私はそれを行うことができます。問題は、レコードが3回以上更新された場合、最も古いレコードが最新のレコードにどのようにホップされたかを正確に知る必要があります。これについては、私たちはセットルールを持っていませんが、一般的に私はcustomer start dateに従っています(そして、ID自体が最初に記録されたライトを投げます)、今はcustomer start dateを使用してすべてのレコードを設定します。私はここにテストケースを含めました。レコードのoldIDを再帰的に更新します

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を見てきましたが、私が最初にそれをやり遂げることができるのであれば、それを行うにはしばらく時間がかかります。

+1

正確に結果がわかりません。ペーストしたテーブルのクエリを行いますか?または特定の列? – chris

+0

ああ、すべてのフィールドを忘れる。投稿した出力では、すべてのcolumsnはオリジナルです。変更/更新したい唯一の列はOLDIDです。残りはクエリの一部です。 *そこにいる必要はありません。 –

+0

@Thecrocodilehunter「古い」がどのように満たされているのか、私は理解していません。規則なしで何かを割り当てることは不可能です。あなたはどのようにあなたの模範をしましたか? –

答えて

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 
+0

上記のクエリを#customerテーブルで実行しましたが、oldidはまったく更新されませんでした –

+0

これは私のサーバー上で見ていきます。 – chris

+1

これで動作するようになりました。しかし、私の論理はあなたとは異なります。私が正しいかどうかわからない。しかし、私の意見では、フォロワーは、古い価値の終わりの後にスタートデートを持っていなければなりません。 – chris

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 
+0

いいえ、何でも感謝します。しかし、ここでの本当の問題は、古いレコードのcontract_idに値を設定することです。私はどうしますか? –

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 
関連する問題