从表值函数的输出更新一组数据

时间:2012-11-02 20:36:18

标签: sql sql-server sql-server-2005 sql-server-2008-r2

我正在尝试编写一个查询,将重复的客户端记录合并到一个记录中。现在我只是构建一个映射表来了解我应该用什么映射。

这是我写的两个函数来帮助我

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

第一个函数成功返回有超过1个记录的所有CLIENT_GUID,第二个函数返回GUID并返回共享&#34;公共信息&#34的所有其他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的人员列表,针对该GUID运行FindDuplicateClientsByClient,并将NEW_CLIENT_GUID的任何结果设置为{ {1}}在不使用游标的情况下输入函数。

这是我使用游标

提出的方法
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 中具有值集的每个结果对我来说似乎不正确。这样做的正确方法是什么?我使用的是SQL Server 2008 R2,但我更喜欢它与SQL Server 2005兼容。

1 个答案:

答案 0 :(得分:0)

已经有两天没有答案,我只是坚持使用我的光标解决方案,因为它的性能足以满足我的需要。

当我不得不循环第二次寻找未在上一次传递中映射的人时,我确实使用了不同的方法,但它只是一个与前一个光标完全相同的while循环。

declare @tmpGuid uniqueidentifier
select @tmpGuid = CLIENT_GUID from #mapping where NEW_CLIENT_GUID is null 
while @@ROWCOUNT > 0
begin   
  --Set the first unset guid to itself
  update #mapping
  set NEW_CLIENT_GUID = @tmpGuid
  where CLIENT_GUID = @tmpGuid

  --set all other duplicates to the guid we just used.
  update #mapping
  set NEW_CLIENT_GUID = @tmpGuid
  where CLIENT_GUID in (select CLIENT_GUID from FindDuplicateClientsByClient(@tmpGuid))
       and NEW_CLIENT_GUID is null

  --get next guid
  select @tmpGuid = CLIENT_GUID from #mapping where NEW_CLIENT_GUID is null 
end
set nocount off
go
相关问题