2013-07-19 138 views
2

的状态可以说,我们有4个领域检查重复的记录

id (INT 11 AUTO_INC) 

email (VAR 50) 

timestamp (INT 11) 

status (INT 1) 

命名record表和表包含以下数据

enter image description here

现在我们可以看到的电子邮件地址[email protected]被复制了4次(时间戳最低的记录是原始记录,之后的所有副本都是重复记录)。多少次使用

SELECT email, count(id) FROM record GROUP BY email HAVING COUNT(id)>1 

我可以很容易地计算使用

SELECT COUNT(DISTINCT email) FROM record 

了独特的记录数我也可以很容易找到的电子邮件地址被复制但现在的商业问题是

如何所有重复记录中有多次STATUS是1?

例如:

因此,所有的数字之和是0 + 1 + 1 + 0 + 2 = 4

这意味着有其中有status = 1在表4点中重复的记录

问题

多少重复的记录有状态= 1?

+0

考虑提供一个sqlfiddle(或适当的ddls无论如何) – Strawberry

+0

关于你的答案的临时评论http://stackoverflow.com/a/18307508/285587 - 与()数组上的这个事情是不正确的,而你的答案在技术上是正确的。 –

+0

@YourCommonSense谢谢,我知道从5.5开始,'()'概念可以用于访问数组值,因此我删除了我的答案并向上投票。再次感谢:) –

回答

1

这是一个更好的新解决方案。它会删除每封电子邮件的第一个条目,然后计算其余条目。阅读起来并不容易,如果可能的话,我会在存储过程中编写它,但这是有效的。

select sum(status) 
    from dude d1 
    join (select email, 
       min(ts) as ts 
      from dude 
     group by email) mins 
using (email) 
where d1.ts != mins.ts; 

sqlfiddle

下面

自己的查询找到原来的答案 “的电子邮件地址被重复多少次使用”

SELECT email, 
     count(id) as duplicates 
    FROM record 
GROUP BY email 
HAVING COUNT(id)>1 

可以很容易地修改答案“有多少条重复记录的状态= 1”

SELECT email, 
     count(id) as duplicates_status_sum 
    FROM record 
GROUP BY email 
WHERE status = 1 
HAVING COUNT(id)>1 

这两个查询都会回答,包括原始行,所以它实际上是“包括原始行的重复”。您可以从金额减去1,如果原来总是有状态1.

SELECT email, 
     count(id) -1 as true_duplicates 
    FROM record 
GROUP BY email 
HAVING COUNT(id)>1 

SELECT email, 
     count(id) -1 as true_duplicates_status_sum 
    FROM record 
GROUP BY email 
WHERE status = 1 
HAVING COUNT(id)>1 
+0

谢谢安德烈亚斯,这将分别给出每个电子邮件地址的号码。我需要获取符合标准的所有这些记录的数量,而不是通过电子邮件分组。所以我想说1000个重复记录的状态= 1,没有通过电子邮件分组,因为有成千上万个电子邮件地址 –

+0

我们如何知道如果我们计数(id)-1,我们将排除原始记录?因为我们没有在这个查询中指定哪一个要排除。这可以包括原来的一个,并排除重复:) –

0

如果我的理解没有错的,然后你的查询应该是

SELECT `email` , COUNT( `id`) AS `tot` 
FROM `record` , (
SELECT `email` AS `emt` , MIN( `timestamp`) AS `mtm` 
FROM `record` 
GROUP BY `email` 
) AS `temp` 
WHERE `email` = `emt` 
AND `timestamp` > `mtm` 
AND `status` =1 
GROUP BY `email` 
HAVING COUNT( `id`) >=1 

首先,我们需要得到最小的时间戳然后发现如果你想总和那些这个时间戳和有状态1.

后插入重复记录则查询

SELECT SUM( `tot`) AS `duplicatesWithStatus1` 
FROM (
SELECT `email` , COUNT( `id`) AS `tot` 
FROM `record` , (
SELECT `email` AS `emt` , MIN( `timestamp`) AS `mtm` 
FROM `record` 
GROUP BY `email` 
) AS `temp` 
WHERE `email` = `emt` 
AND `timestamp` > `mtm` 
AND `status` =1 
GROUP BY `email` 
HAVING COUNT( `id`) >=1 
) AS t 

希望这是你想要的

+0

感谢Suraj,它似乎不会丢弃原始记录,我只需要获取重复的号码,并非全部 –

+0

我编辑了我的答案,因为您需要排除原来的一个,所以我改变了查询从计数(id)到计数(id)-1 – Suraj

+0

我们如何知道如果我们计数(id)-1,我们将排除原始记录?因为我们没有在这个查询中指定哪一个要排除。这可以包括原来的一个,并排除重复:) –

0

你可以得到重复记录的计数有状态= 1通过

select count(*) as Duplicate_Record_Count 
from (select * 
from record r 
where r.status=1 
group by r.email,r.status 
having count(r.email)>1) t1 

下面的查询将返回重复的电子邮件与状态1的计数和时间戳

select r.email,count(*)-1 as Duplicate_Count,min(r.timestamp) as timestamp 
from record r 
where r.status=1 
group by r.email 
having count(r.email)>1 
+0

这是否仅考虑重复记录并忽略原始记录? –

+0

我编辑了我的答案,第一个查询将只返回一个计数,第二个查询将返回带有计数的重复电子邮件 –