选择具有“坏”数据的不同行时聚合行

时间:2012-06-27 16:06:12

标签: sql sql-server tsql

标题有点模糊,但让我告诉你我想做什么,并告诉你我的数据有什么问题。

我需要总结表中所有唯一行的单元格值(大小)。但是我的数据很糟糕"我正在使用MAPI,MAPI返回的邮件大小可能会针对相同的邮件内容进行非确定性区分。

我有两个类似的表/任务:消息和附件。处理附件更容易,因为SHA1哈希始终与附件大小相关。附件数据如下所示(制表符分隔,Excel就绪):

Hash Size
0x0015A93FFFB1726E6647F94F47F4998AC699A455 97
0x0015A93FFFB1726E6647F94F47F4998AC699A455 97
0x0020CE1810B56CC17F6CFD0A0B6121592825F7E5 85
0x0086077DD1E4AF6A38014AB505105B05F8F5311E 62
0x0086077DD1E4AF6A38014AB505105B05F8F5311E 62
0x00A6510EEDB20A27B00B23416CF755715647A351 85
0x011C9258A0E16E25662E8F3BEE8A1462C175C117 87777
0x011C9258A0E16E25662E8F3BEE8A1462C175C117 87777
0x011C9258A0E16E25662E8F3BEE8A1462C175C117 87777
0x011C9258A0E16E25662E8F3BEE8A1462C175C117 87777
0x011C9258A0E16E25662E8F3BEE8A1462C175C117 87777
0x011C9258A0E16E25662E8F3BEE8A1462C175C117 87777
0x011C9258A0E16E25662E8F3BEE8A1462C175C117 87777
0x011C9258A0E16E25662E8F3BEE8A1462C175C117 87777
0x011C9258A0E16E25662E8F3BEE8A1462C175C117 87777

这是我用来获取表格中所有重复附件总大小的查询:

select
    sum(at.sz) as Size
from
(
    select distinct
        Hash,
        sz = Size * ((sum(1) over (partition by Hash)) - 1)
    from
        Attachment
) as at

(我从附件计数中减去1以获得真正的重复计数:总附件 - 1 =此附件的重复数量)

现在,真正的问题在于消息,因为MAPI报告的消息大小包含所有隐藏的垃圾和相同内容+附件的消息大小可能不同(请注意,对于某些具有相同散列的消息,大小不同):

Hash Size
0x001B05F4D041EB0E61ADDEA45A1F7AFAD5C088AB 3248
0x001B05F4D041EB0E61ADDEA45A1F7AFAD5C088AB 3248
0x001B05F4D041EB0E61ADDEA45A1F7AFAD5C088AB 3260
0x001B05F4D041EB0E61ADDEA45A1F7AFAD5C088AB 3260
0x001B05F4D041EB0E61ADDEA45A1F7AFAD5C088AB 3264
0x001B05F4D041EB0E61ADDEA45A1F7AFAD5C088AB 3266
0x00510D4B3A9D42C8D8E236950B7FBBD5FB716698 12040
0x00D92C8EB7E718EF418BC9D843D760FD1F4B208B 3657
0x00D92C8EB7E718EF418BC9D843D760FD1F4B208B 3659
0x00D92C8EB7E718EF418BC9D843D760FD1F4B208B 3671
0x011683250CC8D779EC3F33C23209C26E27E25E73 5143
0x016D424B6B4B7DDB4856D1660ECBFEBDD3ECACCA 3531
0x016D424B6B4B7DDB4856D1660ECBFEBDD3ECACCA 3543
0x016D424B6B4B7DDB4856D1660ECBFEBDD3ECACCA 3549
0x016D424B6B4B7DDB4856D1660ECBFEBDD3ECACCA 3559

对于这样的数据,上面的查询无法返回任何合理的结果,因为不同对的计数并不总是= 1。

我可以选择相同散列的任何一种大小,并在求和中使用它。

1 个答案:

答案 0 :(得分:1)

with HashDups as (
  select Hash,
         (count(*)-1)*max(size) as size
    from Messages
   group by Hash
)
select sum(size) as size from HashDups

相同的结构当然可以很好地与附件配合使用。

我不完全了解不同尺寸的问题。也许以下会更准确。它假设每个“重复”的报告大小是真实的,(副本如何具有不同的大小?)。您可以通过从总和中减去最小和最大尺寸来计算每个哈希值的最小和最大重复大小。然后,您可以计算最小和最大总重复大小。你的最终真实价值应该在这两个极端范围内。

with HashDups as (
  select Hash,
         sum(size)-max(size) as minDupSize,
         sum(size)-min(size) as maxDupSize
    from MAPI
   group by Hash
)
select sum(minSupSize) as minDupSize,
       sum(maxDupSize) as maxDupSize
  from HashDups