ORA_0001,但是主键能重复吗没有重复的,什么原因

解决项目中主键重复无法插入数据的问题 - beliveada - ITeye博客
博客分类:
出现此问题是由于这样:表中之前有一些插入的数据,后期经别人导入数据,再次导入数据时出现如下问题:。
&&& 初步分析,是由于导入数据时,导入了自增的id,而数据库中自增的id始终停留在原始的那个值。印象中,小李同学曾经解决过此问题,是将开始自增的值由现在最大的值+1,即可解决。但苦于自己不是专业的数据库人员,也没有系统学习过这方面的知识。于是,先找了邱同学帮我解决。首先确定了确实是由于上述的情况造成的,则修改了表结构中自增字段的最小开始值,生成代码,然后开始commit。发现此处需要将数据先备份出来,然后再插入数据,才能解决此问题。如果数据库中数据量不大的情况下,这种解决办法还是可以的。但数据量大的情况下,光是导入数据就会很长时间。看来这不是最好的解决办法。于是乎,让系统慢慢的导数据。另外思考,db2应该会提供这种修改自增值开始的方法。于是我们继续查询资料。
&&& 经查找,找到如下资料:
&&&
对于自增序列(GENERATED by default)
  GENERATED by default可以直接通过一般的导入方式加载数据,不过有时候会有一点点小问题,自增序列没有进行分配,也就是说,原来表有50条记录,自增序列的下一次分配值为50,当你已经导入了1000条记录进去了,然后发现自增序列的下一次分配值还是为50,这种事不经常发生,但是偶尔会发生一次,比较郁闷的是,当表继续插入数据的时候,下一次分配就会发生冲突,尤其是如果自增建为主键的时候,会违反唯一约束。
  解决办法:首先找到这个序列分配的最大值,select max(id)
  然后用下边这个命令,alter table tablea alter column restart with max(id)+1
&&& 哈哈,终于找到这种解决办法。速度应该会比上一种解决办法快很对了吧。至少不用再次的插入数据。于是在下一张表中再次出现此问题时,使用如下的sql语句,“alter table QUESTIONNAIRE_RUBRIC_CL1 alter column RUBRIC_INST_ID SET GENERATED ALWAYS restart with 210;”,此语句一执行,那个速度真是超赞哦。看来以后再出现此种情况,就照此方法解决了。
&&&& 另外,在测试自增id是否连续自增时,发现id虽然是顺序自增,但会出现不连续的情况。经邱同学研究,发现建表时,使用了cache。
浏览: 72310 次
来自: 西安
根据您的办法,成功解决!
能说明一下,这个文件保存后,放在那里??我今天也出现这种情况了 ...
可以问下,你的最后解决问题的那段代码怎么放?放到哪里去了?
谢谢分享 正好可以用& & &前几天开发童鞋反馈一个利用load data infile命令导入数据主键冲突的问题,分析后确定这个问题可能是mysql的一个bug,这里提出来给大家分享下。以免以后有童鞋遇到类似问题百思不得其解,难以入眠,哈哈。废话少说,进入正题。
&&&& 拿到问题后,首先查看现场,发现问题表的中记录的最大值比自增列的值要大,那么很明显,当有记录进行插入时,自增列产生的值就有可能与已有的记录主键冲突,导致出错。首先想办法解决问题,通过人工调大自增列的值,保证大于表内已有的主键即可,调整后,导数据正常。问题是解决了,接下来要搞清楚问题原因,什么操作导致了这种现象的发生呢?
& & & 这里有一种可能,即业务逻辑包含更新自增主键的代码,由于mysql的update动作不会同时更新自增列值,若更新主键值比自增列大,也会导致上述现象:记录最大值比自增主键值大。但开发反馈说这张表仅仅存在load data infile操作,不会进行更新主键操作,所以这个解释行不通。继续分析,表中含有唯一约束,会不会和唯一约束有关,线下实验模拟没有重现。后来想想会不会和主备切换有关系,因为前两天做过一次主备切换。于是乎,配合主备环境作了测试,果然和主备切换有关系,一切问题的来源都清晰了。
问题发生的前置条件:
&&&&&& 1.mysql复制基于row模式
&&&&&& 2.innodb表
&&&&&& 3.表含有自增主键,并且含有唯一约束
&&&&&& 4.load data infile 采用replace into语法插入数据【遇到重复唯一约束,直接覆盖】
问题发生的原理:
&&&&&&& 1.主库遇到重复unique约束时,进行replace操作;
&&&&&&& 2.replace在主库上面实际变化为delete+insert,但binlog记录的是update;
&&&&&&& 3.备库重做update动作,更新主键,但由于update动作不会更新自增列值,导致更新后记录值大于自增列值
问题重现实验:
Create table test_autoinc(id int auto_increment, c1 int,c2 varchar(100),primary key(id),unique key(c1));
insert into test_autoinc(c1,c2) values(1,'abc');
insert into test_autoinc(c1,c2) values(2,'abc');
insert into test_autoinc(c1,c2) values(3,'abcdd');
insert into test_autoinc(c1,c2) values(4,'abcdd');
insert into test_autoinc(c1,c2) values(5,'abcdd');
查看自增列值
Show create table
test_autoinc\G
插入5条记录后,自增列值变为6
CREATE TABLE `test_autoinc` (
& `id` int(11) NOT NULL AUTO_INCREMENT,
& `c1` int(11) DEFAULT NULL,
& `c2` varchar(100) DEFAULT NULL,
& PRIMARY KEY (`id`),
& UNIQUE KEY `c1` (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
CREATE TABLE `test_autoinc` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c1` int(11) DEFAULT NULL,
`c2` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `c1` (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=6
DEFAULT CHARSET=utf8
查看表数据
---+------+------
|&&& 1 | abc&
&2 |&&& 2 | abc&
|&&& 3 | abcdd
|&&& 4 | abcdd
|&&& 5 | abcdd
---+------+------
|&&& 1 | abc&
&2 |&&& 2 | abc&
|&&& 3 | abcdd
|&&& 4 | abcdd
|&&& 5 | abcdd
查看binlog位置
show master status\G
记录当前binlog位点,
后续可以查看replace动作产生的binlog事件
mysql-bin.000038
replace操作
replace into test_autoinc(c1,c2)
values(2,'eeee');
影响两条记录,主库replace=
delete+insert
Query OK, 2 rows
(0.00 sec)
查看表数据
---+------+-------
|&&& 1 | abc&&
|&&& 3 | abcdd
|&&& 4 | abcdd
|&&& 5 | abcdd
---+------+-------
|&&& 1 | abc&&
|&&& 3 | abcdd
|&&& 4 | abcdd
|&&& 5 | abcdd
&6 |&&& 2 | eeee&
查看binlog事件
show binlog events in 'mysql-bin.000038'
也可以通过mysqlbinlog工具分析日志,查询从库执行的update语句
| Event_type&&&
---------+---------------
| Query&&&&&&&&
| Table_map&&&&
| Update_rows_v1
| Xid&&&&&&&&&&
查看自增列值
Show create table
此时master的自增列为7,而slave的自增列为6,与表内最大值相同
CREATE TABLE `test_autoinc` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c1` int(11) DEFAULT NULL,
`c2` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `c1` (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=7
CREATE TABLE `test_autoinc` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c1` int(11) DEFAULT NULL,
`c2` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `c1` (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=6
& & &经过第8步操作后,若发生主备切换,slave提供服务,此时通过自增列插入主键6的记录,就会发生主键冲突。
& & &如何解决这个bug?对于replace操作,生成binlog时也生成delete和insert两个事件而非一个update事件;或者在执行update更新主键的同时也更新自增列值。当然了,这个只是纯原理分析,具体采用什么方法解这个问题,要根据mysql内部的实现,避免引入新的问题。这个bug我同事已经提交到社区,&,大家可以看看。
阅读(...) 评论()2014年7月荣获微软MVP称号2013年7月 荣获微软MVP称号2012年7月 荣获微软MVP称号2011年7月 荣获微软MVP称号
2012年2月 总版技术专家分月排行榜第三
2011年11月 Web 开发大版内专家分月排行榜第二
2012年2月 Web 开发大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。查看: 6949|回复: 15
序列达到最大值怎么解决
论坛徽章:1
一个表的主键是用序列生成的,应用程序设置的位数为 4位,现在达到 9999 了,如果序列设置为循环,应该变为0001 ,但是由于它是主键,这样就会造成主键重复。如果使用alter sequence语句来修改序列的定义,把它改为 8位,那样最大值就会变成
,这样可以解决吗?
主键定义:&&BGdoc_id& &&&varchar2&10&& & .
[ 本帖最后由 xatftp 于
22:46 编辑 ]
论坛徽章:12
论坛徽章:304
回复 #1 xatftp 的帖子
这种问题,自己作个测试便知。
论坛徽章:10
这不是技术问题. 是业务规则问题
论坛徽章:24
只要不重复就行
论坛徽章:1
没人知道吗?
论坛徽章:12
回复 #6 xatftp 的帖子
是你火星了还是我火星了?
还是我们上面回帖的人通通被无视了?
论坛徽章:11
原帖由 xatftp 于
08:55 发表
没人知道吗?
你这问题问题的太搞了。
你看弄明白你主键列是多少位的。
论坛徽章:15
先看主键的数据类型, 能否支持8位的数值
论坛徽章:6
原帖由 wxhoracle 于
16:09 发表
这不是技术问题. 是业务规则问题
是啊,如果你业务规则只能4位的话,那上帝也救不了你啦
当初做设计的时候没为以后做考虑...
itpub.net All Right Reserved. 北京皓辰网域网络信息技术有限公司版权所有    
 北京市公安局海淀分局网监中心备案编号: 广播电视节目制作经营许可证:编号(京)字第1149号随笔 - 147&
文章 - 1&评论 - 93&trackbacks - 0
&查找数据库中重复数据T-SQL========第一篇=========在一张表中某个字段下面有重复记录,有很多方法,但是有一个方法,是比较高效的,如下语句:select data_guid from adam_entity_datas a where a.rowid & (select min(b.rowid) from adam_entity_datas b where b.data_guid = a.data_guid)如果表中有大量数据,但是重复数据比较少,那么可以用下面的语句提高效率select data_guid from adam_entity_datas where data_guid in (select data_guid from adam_entity_datas group by data_guid having count(*) & 1)此方法查询出所有重复记录了,也就是说,只要是重复的就选出来,下面的语句也许更高效select data_guid from adam_entity_datas where rowid in (select rid from (select rowid rid,row_number()over(partition by data_guid order by rowid) m from adam_entity_datas) where m && 1)目前只知道这三种比较有效的方法。第一种方法比较好理解,但是最慢,第二种方法最快,但是选出来的记录是所有重复的记录,而不是一个重复记录的列表,第三种方法,我认为最好。========第二篇=========select usercode,count(*) & & & from ptype & & group by usercode & & having count(*) &1 &&========第三篇=========找出重复记录的ID:&select ID & & &from & & &&( & & & & select ID ,count(*) as Cnt&from 要消除重复的表&group by ID&) T1&t&1 &&删除数据库中重复数据的几个方法 &&&& & & & &数据库的使用过程中由于程序方面的问题有时候会碰到重复数据,重复数据导致了数据库部分设置不能正确设置…… & &&方法一 &&&& & & &declare @max integer,@id integer &&&& & & &declare cur_rows cursor local for select 主字段,count(*) from & &&&& & & & & &表名 group by 主字段 having count(*) & 1&  open cur_rows&  fetch cur_rows into @id,@max&  while @@fetch_status=0&  begin&  select @max = @max -1&  set rowcount @max&  delete from 表名 where 主字段 = @id&  fetch cur_rows into @id,@max&  end&  close cur_rows&  set rowcount 0 &&&& &方法二 &&有两个意义上的重复记录,一是完全重复的记录,也即所有字段均重复的记录,二是部分关键字段重复的记录,比如Name字段重复,而其他字段不一定重复或都重复可以忽略。 &&&& &1、对于第一种重复,比较容易解决,使用 &&&& & &select distinct * from tableName &&&& &就可以得到无重复记录的结果集。 &&如果该表需要删除重复的记录,可以按以下方法删除 &&select distinct * into #Tmp from tableName &&drop table tableName &&select * into tableName from #Tmp &&drop table #Tmp &&&& &2、这类重复问题通常要求保留重复记录中的第一条记录,*作方法如下 &&假设有重复的字段为Name,Address,要求得到这两个字段唯一的结果集 && select identity(int,1,1) as autoID, * into #Tmp from & &&tableName && select min(autoID) as autoID into #Tmp2 from #Tmp group by & &&Name,autoID &&select * from #Tmp where autoID in(select autoID from & &&#tmp2) &&&& &最后一个select即得到了Name,Address不重复的结果集 &&更改数据库中表的所属用户的两个方法 &&大家可能会经常碰到一个数据库备份还原到另外一台机器结果导致所有的表都不能打开了,原因是建表的时候采用了当时的数据库用户…… & &&========第四篇=========如何查询数据库中的重复记录?比如说有个表中的数据是这样:---------aaabbc---------查询出的结果是:记录 & 数量a & & & & & 3b & & & & & 2c & & & & & 1怎样写这个SQL语句?-----------------------select distinct(name),count(*) from t-------------------------------------想出来了,这样就可以排序了。select a1,count(a1) & as total from tablename group by a1 order by total desc--------------------------------------select distinct(a1),count(a1) as total from tablename group by a1 order by total desc加个distinct更有效率--------------------------------------------------------------select p.*, m.* from table1 p left join table2 m on p.item1=m.item2 where p.item3='#$#@%$@' order by p.item3 asc limit 10就类似这么写========第五篇=========如何查找数据库中的重复记录? 能在Access中用的方法&----------------------------------------------------------------------select *&from 表 A inner join (select 字段1,字段2 from 表 group by 字段1,字段2 having Count(*)&1) B on A.字段1=B.字段1 and A.字段2=B.字段2&--------------------------------------------------------问题:根据其中几个字段判断重复,只保留一条记录,但是要显示全部字段,怎么查询,谢谢!!&比如&字段1 字段2 字段3 字段4&a & & &b & & &c & & & 1&a & & &b & & &c & & & 1&a & & &b & & &d & & & 2&a & & &b & & &d & & & 3&b & & &b & & &d & & & 2&想得到的结果为&a & & &b & & &c & & & 1&a & & &b & & &d & & & 2(或者3)&b & & &b & & &d & & & 2&说明,根据字段1,2,3组合不重复,字段4 不考虑,得到了3个记录&但是也要显示字段4。&方法一: &&可以用临时表的方法来解决:&CurrentProject.Connection.Execute "drop table temptable"&CurrentProject.Connection.Execute "select * into temptable from 表2 where 1=2"&CurrentProject.Connection.Execute "insert into temptable(字段1,字段2,字段3) SELECT DISTINCT 表2.字段1, 表2.字段2, 表2.字段3 FROM 表2;"&CurrentProject.Connection.Execute "UPDATE temptable INNER JOIN 表2 ON (表2.字段1 = temptable.字段1) AND (表2.字段2 = temptable.字段2) AND (表2.字段3 = temptable.字段3) SET temptable.字段4 = [表2].[字段4];"&方法二:&可以直接使用一个SELECT查询筛选出需要的数据:&可以假定第四字段都选值最小的&SELECT [1],[2], [3], Min([4]) AS Min4&FROM 表1&GROUP BY 表1.[1], 表1.[2], 表1.[3];&问题:表2&id & NAME & r1 & &r2&1 & &1 & & &w & & ee&1 & &1 & & &1 & & 1232&1 & &2 & & &123 & 123&1 & &2 & & &12 & &434&1 & &2 & & &123 & 123&2 & &1 & & &123 & 123&ID 为数值,NAME 为字符。每条记录没有唯一标识。&要求取得 ID 和 NAME 合并后不重复的记录,如有重复保留其中一条即可,但要显示所有记录。&回答:&SELECT a.*, (select top 1 r1 from 表2 as a1 where a1.id=a.id and a1.name=a.name) AS r1, (select top 1 r2 from 表2 as a2 where a2.id=a.id and a2.name=a.name) AS r2&FROM [SELECT DISTINCT 表2.id, 表2.NAME&FROM 表2]. AS&SELECT a.*, dlookup("r1","表2","id=" & a.id & & " and name='"& a.name & "'") AS r1, dlookup("r2","表2","id=" & a.id & & " and name='"& a.name & "'") AS r2&FROM [SELECT DISTINCT 表2.id, 表2.NAME&FROM 表2]. AS&注意,上述代码中由于没有唯一标识列,因此显示的 R1 R2 的先后次序无从确定,一般是按输入的先后顺序,但是微软没有官方资料说明到底按哪个顺序,请网友注意。&请注意,上述表2为没有唯一标识字段,如果现在再建立一个自动编号字段“主键”则可以用以下代码&SELECT a.ID, a.name, b.r1, b.r2, b.主键&FROM (SELECT 表2.id, 表2.NAME, Min(表2.主键) AS 主键&FROM 表2&GROUP BY 表2.id, 表2.NAME) AS a inner JOIN 表2 AS b ON a.主键=b.主键;&========第六篇=========1.查询数据库中重复的记录:select realname,count(*) from users group by realname having count(*)&1&========第七篇=========SELECT T0.ItemCode, T0.ItemName FROM OITM T0 WHERE exists (select 1 from OITM A where A.CODEBARS = TO.CODEBARS And A.ItemCode & & TO.ItemCode)========第八篇=========相信很多人在查询数据库时都会碰到检索某表中不重复记录的时候,提到检索不重复记录,马上想到的肯定是Distinct或者Group By分组,小弟在初次使用的时候碰到了一些麻烦,这里拿出来与大家分享,希望对更多的朋友有所帮助!&& &先看看数据库表结构:&& & & &表名: TEST 字段: Id,A,B,C,D&& & & &其中B字段包含重复值;IdA BC D111 a34 bvb222 a35 fgfg333 dht sdf444 a345 de555 csfsf sscv666 brt fg&& &&&&&& &下面我们来看看用什么样的SQL语句检索出不含重复记录的数据:使用Distinct关键字&& &Distinct关键字主要用来在SELECT查询记录中根据某指定字段的值去除重复记录&& &SELECT DISTINCT [字段名] FROM [表名] WHERE [检索条件字句]&& &所以用这样一句SQL就可以去掉重复项了:&& & &[color=]SELECT DISTINCT (B) FROM TEST&& &但是:&& &这里有一个非常非常需要注意的地方:&& &SELECT DISTINCT [字段名]后面不能再跟其他的字段,否则检索出来的记录仍然会含有重复项;&& & &错误写法:&& & & & & &SELECT DISTINCT [字段名] ,[其他字段名] FROM [表名] WHERE [检索条件字句]&& &&& &实际上,我们上面SQL语句结果集里就只有B字段;(一般情况下,这种结果应该是很难满足需求的)&& &如果我们的记录集里还需要有其他字段值,那怎么办呢?实际上,我们完全可以用另一种办法来解决问题;只是需要用到子查询而已!使用GROUP BY 分组&& &有一点需要注意:&& & & 使用带有GROUP BY字句的查询语句时,在SELECT列表指定的列要么是GROUP BY 指定的列,要么包含聚合组函数&& &所以用这样一句SQL就可以去掉重复项了:[color=]SELECT * FROM TEST WHERE id in (SELECT MIN(id) FROM TEST GROUP BY B)&& &这样就得到我们想要的结果集了:&&&IdA BC D111 a34 bvb333 dht sdf555 csfsf sscv666 brt fg&& & &&&& & &&========第九篇======mysql===----------------------------------------------------------------------我的mysql表中的帐号是8位的随机数,我现在想查帐号有没有重复的,应该怎样操作,&----------------------------------------------------------------------select count(*) as num,帐号 from TABLE GROUP BY 帐号&num & 1 就有重复!&========第十篇====(着急的人直接看红字)=====在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是distinct只能返回它的目标字段,而无法返回其它字段,这个问题让我困扰了很久,用distinct不能解决的话,我只有用二重循环查询来解决,而这样对于一个数据量非常大的站来说,无疑是会直接影响到效率的。所以我花了很多时间来研究这个问题,网上也查不到解决方案,期间把容容拉来帮忙,结果是我们两人都郁闷了。。。。。。。。。下面先来看看例子:&& & table&& id name&& 1 a&& 2 b&& 3 c&& 4 c&& 5 b库结构大概这样,这只是一个简单的例子,实际情况会复杂得多。比如我想用一条语句查询得到name不重复的所有数据,那就必须使用distinct去掉多余的重复记录。select distinct name from table得到的结果是:&& name&& a&& b&& c好像达到效果了,可是,我想要得到的是id值呢?改一下查询语句吧:select distinct name, id from table结果会是:&& id name&& 1 a&& 2 b&& 3 c&& 4 c&& 5 bdistinct怎么没起作用?作用是起了的,不过他同时作用了两个字段,也就是必须得id与name都相同的才会被排除。。。。。。。我们再改改查询语句:select id, distinct name from table很遗憾,除了错误信息你什么也得不到,distinct必须放在开头。难到不能把distinct放到where条件里?能,照样报错。。。。。。。很麻烦吧?确实,费尽心思都没能解决这个问题。没办法,继续找人问。拉住公司里一JAVA程序员,他给我演示了oracle里使用distinct之后,也没找到mysql里的解决方案,最后下班之前他建议我试试group by。试了半天,也不行,最后在mysql手册里找到一个用法,用group_concat(distinct name)配合group by name实现了我所需要的功能,兴奋,天佑我也,赶快试试。报错。。。。。。。。。。。。郁闷。。。。。。。连mysql手册也跟我过不去,先给了我希望,然后又把我推向失望,好狠哪。。。。再仔细一查,group_concat函数是4.1支持,晕,我4.0的。没办法,升级,升完级一试,成功。。。。。。终于搞定了,不过这样一来,又必须要求客户也升级了。突然灵机一闪,既然可以使用group_concat函数,那其它函数能行吗?赶紧用count函数一试,成功,我。。。。。。。想哭啊,费了这么多工夫。。。。。。。。原来就这么简单。。。。。。现在将完整语句放出:select *, count(distinct name) from table group by name结果:&& id name count(distinct name)&& 1 a 1&& 2 b 1&& 3 c 1最后一项是多余的,不用管就行了,目的达到。。。。。唉,原来mysql这么笨,轻轻一下就把他骗过去了,郁闷也就我吧(对了,还有容容那家伙),现在拿出来希望大家不要被这问题折腾。哦,对,再顺便说一句,group by 必须放在 order by 和 limit之前,不然会报错,差不多了,发给容容放网站上去,我继续忙碌。。。。。。-----------------------------------------------------------------------------------------更郁闷的事情发生了,在准备提交时容容发现,有更简单的解决方法。。。。。。select id, name from table group by nameselect * from table group by name========第十一篇=========查询及删除重复记录的方法(一)1、查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断select * from peoplewhere peopleId in (select peopleId from people group by peopleId having count(peopleId) & 1)2、删除表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断,只留有rowid最小的记录delete from people&where peopleId in (select peopleId from people group by peopleId having count(peopleId) & 1)and rowid not in (select min(rowid) from people group by peopleId having count(peopleId )&1)3、查找表中多余的重复记录(多个字段)&select * from vitae awhere (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) & 1)4、删除表中多余的重复记录(多个字段),只留有rowid最小的记录delete from vitae awhere (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) & 1)and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)&1)5、查找表中多余的重复记录(多个字段),不包含rowid最小的记录select * from vitae awhere (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) & 1)and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)&1)(二)比方说在A表中存在一个字段“name”,而且不同记录之间的“name”值有可能会相同,现在就是需要查询出在该表中的各记录之间,“name”值存在重复的项;Select Name,Count(*) From A Group By Name Having Count(*) & 1如果还查性别也相同大则如下:Select Name,sex,Count(*) From A Group By Name,sex Having Count(*) & 1(三)方法一declare @max integer,@id integerdeclare cur_rows cursor local for select 主字段,count(*) from 表名 group by 主字段 having count(*) &; 1open cur_rowsfetch cur_rows into @id,@maxwhile @@fetch_status=0beginselect @max = @max -1set rowcount @maxdelete from 表名 where 主字段 = @idfetch cur_rows into @id,@maxendclose cur_rowsset rowcount 0  方法二  有两个意义上的重复记录,一是完全重复的记录,也即所有字段均重复的记录,二是部分关键字段重复的记录,比如Name字段重复,而其他字段不一定重复或都重复可以忽略。  1、对于第一种重复,比较容易解决,使用select distinct * from tableName  就可以得到无重复记录的结果集。  如果该表需要删除重复的记录(重复记录保留1条),可以按以下方法删除select distinct * into #Tmp from tableNamedrop table tableNameselect * into tableName from #Tmpdrop table #Tmp  发生这种重复的原因是表设计不周产生的,增加唯一索引列即可解决。  2、这类重复问题通常要求保留重复记录中的第一条记录,操作方法如下  假设有重复的字段为Name,Address,要求得到这两个字段唯一的结果集select identity(int,1,1) as autoID, * into #Tmp from tableNameselect min(autoID) as autoID into #Tmp2 from #Tmp group by Name,autoIDselect * from #Tmp where autoID in(select autoID from #tmp2)  最后一个select即得到了Name,Address不重复的结果集(但多了一个autoID字段,实际写时可以写在select子句中省去此列)(四)查询重复select * from tablename where id in (select id from tablename&group by id&having count(id) & 1)
阅读(...) 评论()

我要回帖

更多关于 mysql 主键重复 的文章

 

随机推荐