无法在SQL中获得重复计数

时间:2014-04-13 18:45:24

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

我正在尝试找到一种方法来在SQL中执行一些重复的电子邮件/帐号。此数据中的Act_no和Act_emails未链接(含义1 Act_no不一定具有相同的电子邮件)。

 | P_key | Salesman | Act_No |  Act_Email |     Date/Time    |
 |   1   |   Max    |   1    | doe@xx.com | 2014-04-13 09:00 |
 |   2   |   Max    |   2    | doe@xx.com | 2014-04-13 08:00 |
 |   3   |   Max    |   2    | cat@xx.com | 2014-04-13 08:00 |
 |   4   |   Sue    |   2    | mom@xx.com | 2014-04-13 08:00 |
 |   5   |   Sue    |   3    | cat@xx.com | 2014-04-13 09:00 |
 |   6   |   Joe    |   4    | x_x@xx.com | 2014-04-13 10:00 |
 |   8   |   Joe    |   5    | mom@xx.com | 2014-04-13 09:00 |
 |   7   |   Joe    |   2    | zip@xx.com | 2014-04-13 11:00 |

我需要对此信息做些如下:

对于每个推销员,我需要为整个表格计算重复的Act_Emails或Act_Nos        - 所以Max会为他的所有记录显示3(由于桌子中的doe@xx.com两次为max而cat@xx.com不止一次在桌面上(尽管cat@xx.com仅在最大值时)一旦)。        - Joe会显示他的2条记录,因为mom@xx.com(P_key' 4和8)和Act_No 2(P_keys 2,3,4和7)都不止一次在表中,但是x_x@xx.com和Act_no 4只在表格中出现一次。

接下来的部分我也遇到了麻烦,说实话,我也不知道该往哪里去。我需要做的只是为每个重复的Act_no或Act_email计算最近的Act_no或Act_email以获取最后一个查询的结果(我也需要计算)(抱歉,如果这令人困惑)。

所以现在我知道doe@xx.com不止一次出现在桌面上,我需要计算doe@xx.com,仅用于Max的最近一次通话(So P_key 1)。苏将有1个最近分配的dupes,因为p_key = 8的mam@xx.com是后来的电话,但是cat@xx.com晚于p_key = 8. Joe最近有两个,因为Act_no = 2晚于P_key = 4,3和2,并且mom@xx.com晚于p_key = 4。

所以我所寻找的基本上类似于下面的内容

 Salesman | Count of Dupes | Most recent Dupe Assigned
   Max    |       3        |           1
   Sue    |       2        |           1
   Joe    |       2        |           2

这是我到目前为止第一部分的工作,但它实际上并没有达到我想要的,这只是限制每个销售人员的计数,而不是真正计算整个表的重复对于每个推销员:

SELECT Salesman, COUNT(*)
FROM Table t
GROUP BY Salesman
HAVING COUNT(Act_No) > 1 OR  COUNT(Act_Email) > 1;

我们正在与每个客户和电子邮件合作,我们希望更改为每个销售员的佣金支付合并,只包括不同的Act_No和电子邮件。因此,如果一个帐户或电子邮件与两个销售人员交谈,我们希望该记录仅计入他们与之交谈的最新销售人员。

简而言之,我希望为每个销售人员显示每个销售人员有多少重复的act_no和/或电子邮件,然后显示每个销售人员在分配最新记录时将拥有多少记录他们。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

此查询是否回答了您的第一个问题?让我知道,并在此基础上我可以帮助解决第二个问题。

WITH
  EmailCounts AS (
    SELECT Act_Email
    FROM [Table]
    GROUP BY Act_Email
    HAVING COUNT(*) > 1
  ),
  ActCounts AS (
    SELECT Act_No
    FROM [Table]
    GROUP BY Act_No
    HAVING COUNT(*) > 1
  )
SELECT
  Salesman,
  COUNT(COALESCE(EmailCounts.Act_Email, CAST(ActCounts.Act_No AS VARCHAR))) AS Dups
FROM [Table]
LEFT JOIN EmailCounts ON [Table].Act_Email = EmailCounts.Act_Email
LEFT JOIN ActCounts ON [Table].Act_No = ActCounts.Act_No
GROUP BY Salesman

(注意:您的示例查询将表命名为“Table”,这是一个保留字,因此必须用方括号分隔。)

此查询以一些“公用表格式”(CTE)开始 - 这是WITH EmailCounts AS ...部分 - 获取重复电子邮件列表和重复帐号列表。

根据您的样本数据,电子邮件的CTE结果将是:

Act_Email
----------
cat@xx.com
doe@xx.com
mom@xx.com

帐号的CTE结果仅为帐户#2:

Act_No
------
2

主要查询按销售代表连接到两个列表,并计算所有存在非空电子邮件或帐号的行。它的中间结果在COUNT之前,如下所示:

Salesman Act_Email  Act_No
-------- ---------- ------
Max      doe@xx.com NULL    <- counted (email not null)
Max      doe@xx.com 2       <- counted (both not null)
Max      cat@xx.com 2       <- counted (both not null)
Sue      mom@xx.com 2       <- counted (both not null)
Sue      cat@xx.com NULL    <- counted (email not null)
Joe      NULL       NULL    <- not counted (both null)
Joe      mom@xx.com NULL    <- counted (email not null)
Joe      NULL       2       <- counted (act_no not null)

当应用计数和分组时,结果如下:

Salesman Dups
-------- ----
Joe      2
Max      3
Sue      2

COALESCE将返回它在参数中找到的第一个非null值,如果所有参数都为null,则返回NULL。如果它返回NULL,则COUNT将不计算该行。

另请注意,在我为帐号添加COALESCE之前,CAST对我不起作用,使其与电子邮件的数据类型相同。