重複するクライアント レコードを 1 つのレコードにマージするクエリを作成しようとしています。現在、何を何にマッピングする必要があるかを知るために、マッピングテーブルを作成しています。
これを支援するために私が書いた2つの関数を次に示します
CREATE FUNCTION FindDuplicateClients ()
RETURNS TABLE AS RETURN
(
select distinct CLIENT_GUID
from CLIENTS c
inner join
(
select FIRST_NAME, LAST_NAME, HOME_PHONE
from CLIENTS
group by FIRST_NAME, LAST_NAME, HOME_PHONE
having COUNT(*) > 1
) t on c.FIRST_NAME = t.FIRST_NAME and c.LAST_NAME = t.LAST_NAME and c.HOME_PHONE = t.HOME_PHONE)
go
--Find other clients that map to this client
CREATE FUNCTION FindDuplicateClientsByClient (@Client uniqueidentifier)
RETURNS TABLE AS RETURN
(
select distinct CLIENT_GUID
from CLIENTS c
inner join
(
select x.FIRST_NAME, x.LAST_NAME, x.HOME_PHONE
from CLIENTS x
inner join
(
select FIRST_NAME, LAST_NAME, HOME_PHONE
from CLIENTS
where CLIENT_GUID = @Client
) y on x.FIRST_NAME = y.FIRST_NAME and x.LAST_NAME = y.LAST_NAME and x.HOME_PHONE = y.HOME_PHONE
group by x.FIRST_NAME, x.LAST_NAME, x.HOME_PHONE
having COUNT(*) > 1
) t on c.FIRST_NAME = t.FIRST_NAME and c.LAST_NAME = t.LAST_NAME and c.HOME_PHONE = t.HOME_PHONE
where CLIENT_GUID <> @Client)
go
最初の関数CLIENT_GUID
は、2 つ以上のレコードを持つすべての を正常に返します。2 番目の関数は GUID を渡し、「共通情報」 (この場合は名、姓、および自宅の電話番号) を共有する他のすべての GUID を返します。
問題は、マッピング テーブルに記入することです。いくつかの重複を優先するために従わなければならないルールがいくつかあります。たとえば、トランザクションを持っている人は、CLIENT_GUID
変更を加える必要はありませんが、他の GUID をマージすることができます (他の GUID にトランザクションがなかった場合)。
--Create Mapping table
select CLIENT_GUID, CAST(null as uniqueidentifier) as NEW_CLIENT_GUID
into #mapping
from FindDuplicateClients()
--Do not map people who have transactions
update #mapping
set NEW_CLIENT_GUID = CLIENT_GUID
where CLIENT_GUID in (select CLIENT_GUID from trnHistory)
今、ここで私が困っているところです。NEW_CLIENT_GUID
前のクエリで設定した人のリストを取得し、FindDuplicateClientsByClient
その GUID に対して実行し、カーソルを使用せずに関数に渡されたNEW_CLIENT_GUID
結果を設定する方法がわかりません。NEW_CLIENT_GUID
これは、カーソルを使用して思いついた方法です
declare cur cursor LOCAL FAST_FORWARD for select NEW_CLIENT_GUID from #mapping where NEW_CLIENT_GUID is not null
declare @NEW_CLIENT_GUID uniqueidentifier
open cur
fetch next from cur into @NEW_CLIENT_GUID
while @@fetch_status = 0
begin
update #mapping
set NEW_CLIENT_GUID = @NEW_CLIENT_GUID
where CLIENT_GUID in (select CLIENT_GUID from FindDuplicateClientsByClient(@NEW_CLIENT_GUID)) --Find duplicates to this record
and NEW_CLIENT_GUID is null --Do not reassign values that are already set (ie: duplicates that have transactions)
fetch next from cur into @NEW_CLIENT_GUID
end
close cur
deallocate cur
私に#mapping
は、値セットを持つ各結果を反復処理することは正しくないように思えます。これを行う正しい方法は何ですか?私は SQL Server 2008 R2 を使用していますが、SQL Server 2005 とも互換性があるとよいと思います。