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

前端之家收集整理的这篇文章主要介绍了tsql – 将列更新为不同的聚合值前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在创建一个脚本,用于“合并”和删除表中的重复行.该表包含地址信息,并使用整数字段将有关电子邮件的信息存储为位标志(列名lngValue).例如,lngValue& 1 == 1表示其主要地址.

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

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

警告:前面的代码混乱

  1. declare @duplicates table
  2. (
  3. lngInternetPK int,lngContactFK int,lngValue int
  4. )
  5.  
  6. insert into @duplicates (lngInternetPK,lngContactFK,lngValue)
  7. (
  8. select tblminternet.lngInternetPK,tblminternet.lngContactFK,tblminternet.lngValue from tblminternet inner join
  9. (select strAddress,lngcontactfk,count(*) as count from tblminternet where lngValue & 256 <> 256 group by strAddress,lngcontactfk) secondemail
  10. On tblminternet.strAddress = secondemail.strAddress and
  11. tblminternet.lngcontactfk = secondemail.lngcontactfk
  12. where count > 1 and tblminternet.strAddress is not null and tblminternet.lngValue & 256 <> 256 --order by lngContactFK,strAddress
  13. )
  14.  
  15. update @duplicates set lngValue = t.val
  16.  
  17. from
  18. (select (sum(dupes.lngValue) & 65535) as val from
  19. (select here.lngInternetPK,here.lngContactFK,here.lngValue from tblminternet here inner join
  20. (select strAddress,lngcontactfk) secondemail
  21. On here.strAddress = secondemail.strAddress and
  22. here.lngcontactfk = secondemail.lngcontactfk
  23. where count > 1 and here.strAddress is not null and here.lngValue & 256 <> 256) dupes,tblminternet this
  24.  
  25. where this.lngContactFK = dupes.lngContactFK
  26. ) t
  27. 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,并删除所有重复项.

  1. ;WITH bits AS
  2. (
  3. SELECT 0 AS b
  4. UNION ALL
  5. SELECT b + 1
  6. FROM bits
  7. WHERE b < 15
  8. ),v AS
  9. (
  10. SELECT i.*,(
  11. SELECT SUM(value)
  12. FROM (
  13. SELECT MAX(lngValue & POWER(2,b)) AS value
  14. FROM tblmInternet ii
  15. CROSS JOIN
  16. bits
  17. WHERE ii.lngContactFK = i.lngContactFK
  18. AND ii.strAddress = i.strAddress
  19. GROUP BY
  20. b
  21. ) q
  22. ) AS lngNewValue
  23. FROM (
  24. SELECT ii.*,ROW_NUMBER() OVER (PARTITION BY lngContactFK,strAddress ORDER BY lngInternetPK) AS rn
  25. FROM tblmInternet ii
  26. ) i
  27. WHERE rn = 1
  28. )
  29. UPDATE v
  30. SET lngValue = lngNewValue;
  31.  
  32. ;WITH v AS
  33. (
  34. SELECT ii.*,strAddress ORDER BY lngInternetPK) AS rn
  35. FROM tblmInternet ii
  36. )
  37. DELETE v
  38. WHERE rn > 1

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

> SQL Server: aggregate bitwise OR

猜你在找的设计模式相关文章