【问题标题】:SQL counting duplicate emailsSQL 计算重复电子邮件
【发布时间】:2014-03-29 21:22:22
【问题描述】:

我在编写可以在特定条件下查找唯一计数/重复项的查询时遇到问题。我正在尝试从与此类似的表中一次获取计数:

|-P_key-|-----email-----|-act_no-|--Client--|
|   1   | joe@code.com  |    1   |   Jets   |
|   2   | bob@code.com  |    2   |   Jets   |
|   3   | sue@code.com  |  NULL  |   Jets   |
|   4   | joe@code.com  |    1   |   Bills  |
|   5   | bob@code.com  |    2   |   Bills  |
|   6   | bob@code.com  |    2   |   Giants |
|   7   | max@code.com  |    2   |   Giants |
|   8   | ben@code.com  |    5   |   Pats   |

我正在寻找的客户数量如下:

  1. 每个客户的总记录计数
  2. 客户的唯一电子邮件总数
  3. 客户端中唯一帐号的总数
  4. 客户的唯一帐号总数
  5. 客户中的空白帐号计数

我知道我可以使用 group by 和 have 来单独获取这些计数,如下所示:

SELECT COUNT(email)
FROM Table
GROUP BY EMAIL
HAVING COUNT(email) > 1;

但我希望创建一个可以同时返回所有计数的代码。我使用的是 SQL Server 2008。

我希望实现的输出如下(尽管最终数据不一定需要如此旋转):

 |                                  |  Jets  |  Bills | Giants |  Pats |
 | Total emails                     |   3    |    2   |    2   |   1   |
 | unique emails across projects    |   5    |    5   |    3   |   0   |
 | unique account_no across projects|   6    |    6   |    4   |   0   |
 | unique account_no within project |   0    |    0   |    2   |   0   |
 | blank account_no within project  |   1    |    0   |    0   |   0   |

 OR

 |        |  tot unique emails |  duped account_no's | etc...
 | Jets   |   3                |    5                |   
 |Bills   |   2                |    5                |   
 | Giants |   2                |    3                |    
 | Pats   |   1                |    0                |   

感谢您提前提供的所有帮助!

【问题讨论】:

  • 您能否针对问题中的数据显示您想要的输出?

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


【解决方案1】:

首先,您无法获得您提到的结构中的格式。您可以在一行和五列中为每个客户端获取它。

第二,你有非常奇怪的标准。如果一封电子邮件出现在多个客户端,则每个客户端的重复计数包含所有位置的电子邮件总数。好的,但是您需要计算电子邮件出现的次数确定它是否出现在多个客户端上。

解决方案是使用窗口函数计算一堆中间结果。例如,min()max() 窗口函数用于确定电子邮件或帐号是否出现在多个帐户中。

没有 SQL Fiddle 来测试,这是我最好的尝试:

select client,
       count(email) as NumEmails,
       sum(case when email_minclient <> email_maxclieint then email_cnt else 0
           end) as NumEmailsDuped,
       sum(case when actno_minclient <> actno_maxclieint then actno_cnt else 0
           end) as NumActnoDuped,
       sum(case when clientactno_cnt > 1 then clientactno_cnt else 0
           end) as NumActnoDupedWithin,
       sum(case when ActNo is null then 1 else 0 end) as NumActnoNull
from (select t.*,
             count(*) over (partition by email) as email_cnt,
             count(*) over (partition by act_no) as actno_cnt,
             count(*) over (partition by client, act_no) as clientactno_cnt,
             min(client) over (partition by email) as email_minclient,
             max(client) over (partition by email) as email_maxclient,
             min(client) over (partition by act_no) as email_minactno,
             max(client) over (partition by act_no) as email_maxactno
      from table t
     ) t
group by client;

【讨论】:

  • 我升级了你的答案。
【解决方案2】:

这应该会给你想要的结果:

select client,
       count(email) as "Total emails",
       sum(case when email_minclient <> email_maxclient then email_cnt else 0
           end) as "unique emails across projects",
       sum(case when email_minclient <> email_maxclient then actno_cnt else 0
           end) as "unique account_no across projects",
       sum(case when clientactno_cnt > 1 then 1 else 0
           end) as "unique account_no within project",
       sum(case when act_no is null then 1 else 0 end) as "blank account_no within project "
from (select t.*,
             count(*) over (partition by email) as email_cnt,
             count(*) over (partition by act_no) as actno_cnt,
             count(*) over (partition by client, act_no) as clientactno_cnt,
             min(client) over (partition by email) as email_minclient,
             max(client) over (partition by email) as email_maxclient
      from table t  
     ) t
group by client

感谢戈登·林诺夫

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多