Mysql 检查重复记录的状态

Mysql 检查重复记录的状态,mysql,select,duplicates,Mysql,Select,Duplicates,假设我们有一个名为record的表,其中有4个字段 id (INT 11 AUTO_INC) email (VAR 50) timestamp (INT 11) status (INT 1) 该表包含以下数据 现在我们可以看到电子邮件地址test@xample.com重复了4次(时间戳最低的记录是原始记录,之后的所有副本都是重复记录)。我可以使用 SELECT COUNT(DISTINCT email) FROM record 我还可以很容易地找出哪个电子邮件地址被复制了多少次

假设我们有一个名为
record
的表,其中有4个字段

id    (INT 11 AUTO_INC)

email (VAR 50)

timestamp (INT 11)

status (INT 1)
该表包含以下数据

现在我们可以看到电子邮件地址test@xample.com重复了4次(时间戳最低的记录是原始记录,之后的所有副本都是重复记录)。我可以使用

SELECT COUNT(DISTINCT email) FROM record
我还可以很容易地找出哪个电子邮件地址被复制了多少次

SELECT email, count(id) FROM record GROUP BY email HAVING COUNT(id)>1
SELECT email, 
       count(id) as duplicates 
  FROM record 
 GROUP BY email 
HAVING COUNT(id)>1
但现在的商业问题是

所有重复记录中有多少次
STATUS
为1

例如:

  • 为了test@example.com没有状态为1的重复记录
  • 为了second@example.com有1条状态为1的重复记录
  • 为了third@example.com有1条状态为1的重复记录
  • 为了four@example.com没有状态为1的重复记录
  • 为了five@example.com有2条状态为1的重复记录
所以所有数字的总和是
0+1+1+0+2=4

这意味着表中有4条状态为1的重复记录

问题


有多少重复记录的状态为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;

下面的原始答案

您自己的查询以查找“哪个电子邮件地址被复制了多少次使用”

可以轻松修改以回答“状态为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

如果我的理解没有错,那么你的问题应该是

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 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
如果您想要合计,那么查询是

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

希望这是您想要的

您可以通过以下方式获得状态为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 

考虑提供一个SqLoFDLE(或者适当的DDL)一个关于你的答案的临时评论-这个数组上的(东西)是不正确的,而你的答案在技术上是正确的。@你的常识,谢谢,我知道自从5.5以来,<代码>(/>)/Cord>概念可以用来访问数组值,因此我删除了我的答案并赞成你的答案。再次感谢:)除了一条不可靠的评论之外,你还有什么证据吗?这是一个很好的问题,令人尴尬的回答是,我没有做任何研究就认为这条评论是有效的。似乎找不到任何关于我在那里被告知的内容的参考。谢谢Andreas,这将分别给出每个电子邮件地址的数字。我需要获取符合条件的所有此类记录的数量,而不是在输出中按电子邮件分组。因此,我想说1000个重复记录的状态为1,而不是按电子邮件分组,因为有数千个电子邮件地址。我们如何知道,如果我们计算(id)-1,我们将排除原始记录?因为我们没有在这个查询中指定要排除哪一个。这可以包括原始记录并排除重复记录:)谢谢Suraj,它似乎没有丢弃原始记录,我只需要获取重复记录的编号,而不是所有记录。我已经编辑了我的答案,因为您需要排除原始记录,所以我将查询从计数(id)更改为计数(id)-1我们如何知道是否计数(id)-1我们将排除原始记录吗?因为我们没有在这个查询中指定要排除哪一个。这可以包括原始记录并排除重复记录:)我认为您必须首先对时间戳表中的值进行排序,然后再进行排序。抱歉@ØHanky PankyØ我遗漏了您需要排除原始记录的部分。现在修改了查询。这是否只考虑重复记录而忽略原始记录?我已经编辑了我的答案,第一个查询将只返回一个计数,第二个查询将返回带有计数的重复电子邮件