2014-07-08 147 views
1

我有一个表有很多重复记录,即tbl_voter,ID为主键,自动增量。还有另一个表tbl_notes,它为每个选民记录了一些信息。 tbl_notes可以有每个选民零或更多的记录。来自tbl_voter的ID是tbl_notes中的外键。查找重复记录的ID sql

问题是因为在选举人表中有重复,在笔记表中也有重复。

例如:tbl_voter

ID Name Address 
01 abc  xyz 
02 def  pqr 
03 abc  xyz 
04 abc  xyz 
05 abc  xyz 
06 def  pqr 

tbl_notes

Noteid ID  Note 
A001  01  aaaaaa 
A002  02  bbbbbb 
A003  01  cccccc 
A004  03  dddddd 
A005  03  eeeeee 
A006  04  ffffff 
A007  05  gggggg 
A008  01  hhhhhh 

我想找到与原有的所有ID和它们的副本,以便更新tbl_notes

例如: tbl_voter

ID Name Address 
01 abc  xyz 
02 def  pqr 

tbl_notes

Noteid ID  Note 
A001  01  aaaaaa 
A002  02  bbbbbb 
A003  01  cccccc 
A004  01  dddddd 
A005  01  eeeeee 
A006  01  ffffff 
A007  01  gggggg 
A008  01  hhhhhh 

到目前为止,我试图找到重复的记录,但它给了我原有的以及重复的。我需要一个查询将返回我:

RealID  DuplicateID 
01   03 
01   04 
01   05 
02   06 

查询我想:

select * 
from tbl_voter a inner join 
(
select id,firstname,lastname,zip,housenumber,COUNT(*) AS dupes from tbl_voter 
where riding = '35019' 
group by 
firstname,lastname,zip,housenumber 
having count(*) > 1 
) b on a.firstname = b.firstname 
and a.lastname = b.lastname 
and a.zip = b.zip 
and a.firstname is not null 
and b.firstname is not null 
and a.riding='35019' 
and a.housenumber=b.housenumber 
order by a.firstname asc 

如果我添加ID到选择查询,它抛出一个错误说的ID不能在group by查询中使用这是正确的,因为ID将始终不同。

与考虑到的ID查询:

select a.id as realid, b.id as dupid, a.firstname,a.lastname,a.zip,a.housenumber 
from tbl_voter a inner join 
(
select id,firstname,lastname,zip,housenumber,COUNT(*) AS dupes from tbl_voter 
where riding = '35019' 
group by 
id,firstname,lastname,zip,housenumber 
having count(*) > 1 
) b on a.firstname = b.firstname 
and a.lastname = b.lastname 
and a.zip = b.zip 
and a.firstname is not null 
and b.firstname is not null 
and a.riding='35019' 
and a.housenumber=b.housenumber 
order by a.firstname asc 

,如果我得到哪些是重复和以假乱真的ID,我可以更新tbl_notes。

感谢, 沙善

+0

我不记得确切的语法,但我认为'GROUP_CONCAT'可以用来给所有的ID,其中的行,列=行,通过搜索 – andrew

+0

@andrew列ID开始group_concat不适用于MSSQL。我试图寻找替代品,但它基本上建议将ID分组,而不是重复的。我需要重复的,以便在这两个表中更新它们 – Shashank

回答

5

我只专注于找到真正的id和重复的id表。在基本层面上,您试图找到信息被复制的所有id对。从本质上讲,我们可以用这个表开始:

RealID  DuplicateID 
01   01 
01   03 
01   04 
01   05 
03   01 
03   03 
03   04 
03   05 
04   01 
04   03 
04   04 
04   05 
05   01 
05   03 
05   04 
05   05 
02   02 
02   06 
06   02 
06   06 

现在,这是不是你想要的方式的更多信息,但想你的表像这样大大简化了查询。您想要在tbl_voter上创建一个所有非id数据匹配的自联接。

接下来,让我们过滤掉很多信息。只需指定realID必须小于DuplicateID,就可以删除大量不必要的信息。然后,你的表是这样的:

RealID  DuplicateID 
01   03 
01   04 
01   05 
03   04 
03   05 
04   05 
02   06 

这仍然是过剩的信息,但没有那么多。您可以做的最后一件事情是消除多余信息,按重复ID进行分组并选择min(realID)。这会给你你正在寻找的表。该查询看起来是这样的:

Select min(v.id) as RealID, v2.id as DuplicateId 
From tbl_voter v join tbl_voter v2 
    on v.firstname = v2.firstname 
    and v.lastname = v2.lastname 
    and v.zip = v2.zip 
    and v.firstname is not null 
    and v2.firstname is not null 
    and v.riding='35019' 
    and v.riding = v2.riding 
    and v.housenumber=v2.housenumber 
    and v.id < v2.id 
Group by v2.id 
+0

真棒回答,我试图自己做这个,我知道内部连接将需要某处 – CSharper

+0

很好解释,真棒回答!作为一种魅力! :)谢谢詹恩! – Shashank

+0

@Jenn这个查询也会考虑空值吗?我的意思是,如果firstname和lastname是相等的,并且zip值是空的,那么它会匹配还是不匹配?你能帮我画一个相同的查询吗?谢谢! – Shashank

0

您可以尝试生成基于您的键列一个ROW_NUMBER/RANK(不是自动递增一个)并选择所有具有ROW_NUMBER = 1的记录。类似下面

SELECT标识,名字,姓氏,拉链,housenumber一个从 (选择ID,名字,姓氏,拉链,housenumber,ROW_NUMBER()OVER(PARTITION BY ID,名字,姓氏,拉链,housenumber ORDER BY id,firstname,lastname,zip,housenumber)as rowNumber FROM tbl_voter)WHERE rowNumber = 1

+0

不工作伙伴,在Where子句附近发生错误! :( – Shashank

+0

@Shashank你可以请让我知道数据库和版本吗? – Raman