tsql – 将列更新为不同的聚合值

我正在创建一个脚本,用于“合并”和删除表中的重复行.该表包含地址信息,并使用整数字段将有关电子邮件的信息存储为位标志(列名lngValue).例如,lngValue& 1 == 1表示其主要地址.

有两次输入相同电子邮件的情况,但有时会使用不同的lngValues.要解决这个问题,我需要从所有重复项中获取lngValue并将它们分配给一个幸存的记录并删除其余的记录.

到目前为止,我最头疼的是记录的“合并”.我想要做的是将重复记录的按位或所有lngValues放在一起.这是我到目前为止所做的,它只能按位或一起找到所有lngValues的值.

警告:前面的代码混乱

declare @duplicates table
(
lngInternetPK int,lngContactFK int,lngValue int
)

insert into @duplicates (lngInternetPK,lngContactFK,lngValue) 
(
select  tblminternet.lngInternetPK,tblminternet.lngContactFK,tblminternet.lngValue   from tblminternet  inner join 
(select sTraddress,lngcontactfk,count(*) as count from tblminternet where lngValue & 256 <> 256 group by sTraddress,lngcontactfk) secondemail
On tblminternet.sTraddress = secondemail.sTraddress and
tblminternet.lngcontactfk = secondemail.lngcontactfk 
where count > 1 and tblminternet.sTraddress is not null and tblminternet.lngValue & 256 <> 256 --order by lngContactFK,sTraddress
)

update @duplicates set lngValue = t.val

from 
                (select (sum(dupes.lngValue) & 65535) as val from 
                    (select  here.lngInternetPK,here.lngContactFK,here.lngValue from tblminternet here  inner join 
                    (select sTraddress,lngcontactfk) secondemail
                    On here.sTraddress = secondemail.sTraddress     and
                    here.lngcontactfk = secondemail.lngcontactfk 
                    where count > 1 and here.sTraddress is not      null and here.lngValue & 256 <> 256) dupes,tblminternet this

                where this.lngContactFK = dupes.lngContactFK
                ) t
where lngInternetPK in (select lngInternetPK from @duplicates)

编辑:
根据要求,这里有一些示例数据:

表名:tblminternet
列名:
lngInternetPK
lngContactFK
lngValue
sTraddress

第1行示例:
lngInternetPK:1
lngContactFK:1
lngValue:33
sTraddress:“me@myaddress.com”

第2行示例:
lngInternetPK:2
lngContactFK:1
lngValue:40
sTraddress:“me@myaddress.com”

如果这两个合并在这里是期望的结果:
lngInternetPK:1
lngContactFK:1
lngValue:41
sTraddress:“me@myaddress.com”

其他必要规则:
每个联系人可以有多个电子邮件,但每个电子邮件行必须是不同的(每封电子邮件只能显示为一行).

sql Server缺少本机按位聚合,这就是我们需要模拟它们的原因.

这里的主要思想是生成一组从0到15的位,每个位将位掩码应用于该值并选择MAX(这将给出给定位的OR),然后选择SUM(将合并位掩码).

我们只是使用lngValue的新值更新任何给定(lngContactFK,strValue)的第一个lngInternetPK,并删除所有重复项.

;WITH   bits AS
        (
        SELECT  0 AS b
        UNION ALL
        SELECT  b + 1
        FROM    bits
        WHERE   b < 15
        ),v AS
        (
        SELECT  i.*,(
                SELECT  SUM(value)
                FROM    (
                        SELECT  MAX(lngValue & POWER(2,b)) AS value
                        FROM    tblmInternet ii
                        CROSS JOIN
                                bits
                        WHERE   ii.lngContactFK = i.lngContactFK
                                AND ii.sTraddress = i.sTraddress
                        GROUP BY
                                b
                        ) q
                ) AS lngNewValue
        FROM    (
                SELECT  ii.*,ROW_NUMBER() OVER (PARTITION BY lngContactFK,sTraddress ORDER BY lngInternetPK) AS rn
                FROM    tblmInternet ii
                ) i
        WHERE   rn = 1
        )
UPDATE  v
SET     lngValue = lngNewValue;

;WITH    v AS
        (
        SELECT  ii.*,sTraddress ORDER BY lngInternetPK) AS rn
        FROM    tblmInternet ii
        )
DELETE  v
WHERE   rn > 1

有关更详细的说明,请参阅我的博客中的这篇文章

> SQL Server: aggregate bitwise OR

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...