Sql語句問題 刪除相同數據 ( 积分: 50 )

  • 主题发起人 主题发起人 rdy808
  • 开始时间 开始时间
我的那个语句是查处所有重复的纪录,例如有3条一样的语句,它会查处其中的前两条!<br>这条语句可以直接进行Delete!<br>jenhon&nbsp;&nbsp;我正在研究你的语句!
 
SELECT&nbsp;*&nbsp;FROM&nbsp;t_dup&nbsp;a&nbsp;WHERE&nbsp;a.ROWID&nbsp;&lt;&gt;&nbsp;(SELECT&nbsp;MIN(b.ROWID)&nbsp;FROM&nbsp;t_dup&nbsp;b&nbsp;WHERE&nbsp;a.code=b.code)<br>这句我主要看不懂的是它最后的连接&nbsp;&nbsp;WHERE&nbsp;a.code=b.code&nbsp;&nbsp;它是与外面的表进行自连接!!就不太懂了,这种连接方式看起来有点象递归!!
 
SELECT&nbsp;*&nbsp;FROM&nbsp;t_dup&nbsp;a&nbsp;WHERE&nbsp;a.ROWID&nbsp;&lt;&gt;&nbsp;(SELECT&nbsp;MIN(b.ROWID)&nbsp;FROM&nbsp;t_dup&nbsp;b&nbsp;WHERE&nbsp;a.code=b.code)?<br>这语句可以?不是吧?
 
jenhon&nbsp;好像不行啊&nbsp;,你那段语句,上半部分查询结果不多啊,我重复了24行,但只查出来了14行,我的表里面用了4个重复的字段。你试下,看是不是和我一样,我们在讨论一下。
 
http://www.delphibbs.com/keylife/iblog_show.asp?xid=25352
 
SELECT&nbsp;*&nbsp;FROM&nbsp;t_dup&nbsp;a&nbsp;WHERE&nbsp;a.ROWID&nbsp;&lt;&gt;&nbsp;(SELECT&nbsp;MIN(b.ROWID)&nbsp;FROM&nbsp;t_dup&nbsp;b&nbsp;WHERE&nbsp;a.code=b.code)<br>这样写可以直接在&nbsp;oralce里查出重复的纪录&nbsp;,但是我把&nbsp;&lt;&gt;&nbsp;改称&nbsp;not&nbsp;in&nbsp;就不行了,not&nbsp;in&nbsp;&nbsp;和&nbsp;&nbsp;&nbsp;not&nbsp;exists&nbsp;好象是差不多的吧!why?
 
看来ORACLE和SQL&nbsp;SERVER的差别挺大的!!可惜这边没环境测试!
 
&quot;来自:rdy808,&nbsp;时间:2007-6-22&nbsp;9:08:00,&nbsp;ID:3801629<br>jenhon&nbsp;好像不行啊&nbsp;,你那段语句,上半部分查询结果不多啊,我重复了24行,但只查出来了14行,我的表里面用了4个重复的字段。你试下,看是不是和我一样,我们在讨论一下。&nbsp;&nbsp;&quot;<br><br>你能不能尝试减少field1&nbsp;field2&nbsp;field3..&nbsp;的数量,看少到哪里就对了,应该那个字段确实没重复,比如日期:&nbsp;2007-06-22&nbsp;9:00&nbsp;和&nbsp;2007-06-22&nbsp;9:01&nbsp;就不一样。<br><br>你说的重复了24行,但是只查出了14行,是指24行都是相同重复了,应该删除23行;还是指24行可能包含相同的,只列出了其中的14种情况?<br><br>我认为我的语句在逻辑上很清楚了,效率就不敢恭维,但是结构简单,可以放在语句里面自动生成字段的判断。<br>如果逻辑上没什么问题,结果不对就应该有其他原因,毕竟我们不用怀疑计算机的计算能力啊。我没有SQL好调试,帮忙研究啊。<br><br>帮忙调试这2个:&nbsp;<br>select&nbsp;*&nbsp;from&nbsp;table1&nbsp;<br>where&nbsp;<br>field1&nbsp;in&nbsp;(select&nbsp;field1&nbsp;from&nbsp;table1&nbsp;group&nbsp;by&nbsp;field1&nbsp;having&nbsp;count(*)&gt;1)<br>and&nbsp;field2&nbsp;in&nbsp;(select&nbsp;field2&nbsp;from&nbsp;table1&nbsp;group&nbsp;by&nbsp;field2&nbsp;having&nbsp;count(*)&gt;1)<br>....count(*)&gt;1)<br><br>比较:<br>select&nbsp;min(id)&nbsp;as&nbsp;id1,field1,field2,....&nbsp;&nbsp;<br>from&nbsp;table1&nbsp;<br>group&nbsp;by&nbsp;field1,field2,....&nbsp;<br>having&nbsp;count(*)&gt;1)<br><br>看结果的不同之处啊。
 
刚才认真看了angellover的算法,是一个很不错的方法,结果应该对的,就是不知道ORACLE能不能支持&nbsp;delete&nbsp;from&nbsp;left&nbsp;join&nbsp;,不行的话,真是太可惜了。<br><br><br>另外:<br>来自:rdy808,&nbsp;时间:2007-6-21&nbsp;16:57:27,&nbsp;ID:3801389<br>你的方法我正在消化,谢谢!<br>SELECT&nbsp;*&nbsp;FROM&nbsp;t_dup&nbsp;a&nbsp;WHERE&nbsp;a.ROWID&nbsp;&lt;&gt;&nbsp;(SELECT&nbsp;MIN(b.ROWID)&nbsp;FROM&nbsp;t_dup&nbsp;b&nbsp;WHERE&nbsp;a.code=b.code)<br>我这个是另一种方法,不太懂这种连接,你能帮我解释下吗?&nbsp;&nbsp;<br><br>这个语句也是很简洁,不过结果不对,取MIN(B.ROWID)没有分组条件,加入分组条件,又不能查找了。还有不知道ORACLE怎么做到&nbsp;&lt;&gt;连接&nbsp;字段和组合,MSSQL一般都是NOT&nbsp;IN吧。
 
学习了各位想法,发现自己绕了一个大弯,我的后半部的条件已经可以做到了:<br>delete&nbsp;from&nbsp;table1<br>where&nbsp;<br>id&nbsp;not&nbsp;in&nbsp;<br>&nbsp;(select&nbsp;id1&nbsp;as&nbsp;id&nbsp;from<br>&nbsp;&nbsp;&nbsp;(select&nbsp;min(id)&nbsp;as&nbsp;id1,field1,field2,....&nbsp;&nbsp;from&nbsp;table1<br>&nbsp;&nbsp;&nbsp;group&nbsp;by&nbsp;field1,field2,....&nbsp;having&nbsp;count(*)&gt;1)<br>&nbsp;)<br><br>(之所以绕弯了,是因为我在想的是我手上的一个没解决的类似的问题——根本就是没ID区别的,就是一大堆相同重复的记录去删除重复的。<br>不用真实的临时表应该没办法解决,重复的记录所有字段都一样...)
 
DELETE&nbsp;TABLENAME&nbsp;From&nbsp;TABLENAME&nbsp;Left&nbsp;Join&nbsp;(Select&nbsp;Min(ID)&nbsp;as&nbsp;ID,&nbsp;Filed1&nbsp;From&nbsp;TABLENAME&nbsp;Group&nbsp;By&nbsp;Filed1)&nbsp;as&nbsp;T&nbsp;On&nbsp;(TABLENAME.ID&nbsp;=&nbsp;T.ID)&nbsp;Where&nbsp;T.ID&nbsp;Is&nbsp;Null<br>这个方法非常正确,十分感谢分享!&nbsp;&nbsp;谢谢上面三位朋友,我们可以继续讨论西面的问题<br>有没有朋友可以帮我解释下<br>select&nbsp;*&nbsp;from&nbsp;pmm_proj_ctl_etaetdcfm&nbsp;a&nbsp;where&nbsp;a.rowid&nbsp;&lt;&gt;&nbsp;(select&nbsp;min(b.rowid)&nbsp;from&nbsp;pmm_proj_ctl_etaetdcfm&nbsp;b&nbsp;where&nbsp;a.po_number=b.po_number&nbsp;and&nbsp;a.po_item=b.po_item)<br>这种方法是怎么样的一种连接方式!!!
 
DELETE&nbsp;TABLE&nbsp;WHERE&nbsp;(NOT&nbsp;ID&nbsp;IN&nbsp;(<br>&nbsp;&nbsp;SELECT&nbsp;MIN(ID)&nbsp;AS&nbsp;ID&nbsp;<br>&nbsp;&nbsp;FROM&nbsp;TABLE<br>&nbsp;&nbsp;GROUP&nbsp;BY&nbsp;Field1,Field2&nbsp;...&nbsp;<br>&nbsp;&nbsp;))
 
我觉得用一条语句写牵强了点:<br>用个proc&nbsp;来处理简单点:<br><br>proc&nbsp;a<br>as<br>begin<br>&nbsp;&nbsp;declare&nbsp;&nbsp;@xh&nbsp;int&nbsp;<br>&nbsp;&nbsp;alter&nbsp;table&nbsp;tablename&nbsp;add&nbsp;xh&nbsp;int&nbsp;null<br>&nbsp;&nbsp;set&nbsp;@xh&nbsp;=&nbsp;1<br>&nbsp;&nbsp;update&nbsp;tablename&nbsp;set&nbsp;xh&nbsp;=&nbsp;@xh,@xh&nbsp;=&nbsp;@xh&nbsp;+&nbsp;1<br>&nbsp;&nbsp;select&nbsp;id,min(xh)&nbsp;xh&nbsp;into&nbsp;#m&nbsp;from&nbsp;tablename&nbsp;group&nbsp;by&nbsp;id&nbsp;<br>&nbsp;&nbsp;delete&nbsp;tablename&nbsp;from&nbsp;tablename&nbsp;a,#m&nbsp;b&nbsp;where&nbsp;a.id&nbsp;=&nbsp;b.id&nbsp;and&nbsp;a.xh&nbsp;&gt;&nbsp;b.xh&nbsp;<br>&nbsp;&nbsp;alter&nbsp;table&nbsp;tablename&nbsp;drop&nbsp;xh&nbsp;<br><br>end
 
这么多啊&nbsp;我还是来写一个吧<br>select&nbsp;字段1&nbsp;字段2...&nbsp;into&nbsp;#temp&nbsp;from&nbsp;table(查询字段不包括ID的所有字段)<br>delete&nbsp;from&nbsp;table&nbsp;<br>insert&nbsp;into&nbsp;table&nbsp;select&nbsp;*&nbsp;from&nbsp;#temp&nbsp;group&nbsp;by&nbsp;字段1&nbsp;字段2...(所有字段,如果ID的自动增加的就不用插入了,&nbsp;不是的话&nbsp;就自己添加就好了&nbsp;)
 
现在用ID来进行条件检测的方法基本都是可行的.<br>19801125w&nbsp;的兄弟用的是oracle,弄了个proc&nbsp;复杂了,方法可行,其实在oracle中我说的那个方法,一句搞定,但是还是没想出来时一种什么样的连接,这几天在看大学的教材,也找不到,我想大家来研究下这种奇特的方法,这样有点意思啊!
 
这句我主要看不懂的是它最后的连接&nbsp;&nbsp;WHERE&nbsp;a.code=b.code&nbsp;&nbsp;它是与外面的表进行自连接!!就不太懂了,这种连接方式看起来有点象递归!!<br>-----------------------------------------------------------------------<br>你想想not&nbsp;in的原理就不会这么认为它特别了!<br>假设:<br>table1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;table2<br>ID&nbsp;&nbsp;&nbsp;&nbsp;NAME&nbsp;&nbsp;&nbsp;SC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name<br>001&nbsp;&nbsp;&nbsp;AA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;88&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AA<br>001&nbsp;&nbsp;&nbsp;BB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;86&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CC<br>001&nbsp;&nbsp;&nbsp;CC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;78&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>001&nbsp;&nbsp;&nbsp;DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;68<br>现在我要找出在table1中存在而table2中不存在的记录:<br>001&nbsp;&nbsp;&nbsp;BB&nbsp;&nbsp;86<br>001&nbsp;&nbsp;&nbsp;DD&nbsp;&nbsp;68<br>sql:<br>SELECT&nbsp;DISTINCT&nbsp;*&nbsp;FROM&nbsp;TABLE1&nbsp;WHERE&nbsp;TABLE1.NAME&nbsp;NOT&nbsp;IN(SELECT&nbsp;NAME&nbsp;FROM&nbsp;TABLE2&nbsp;WHERE&nbsp;TABLE2.NAME&nbsp;=&nbsp;TABLE1.NAME);<br>原理上TABLE2.NAME&nbsp;=&nbsp;TABLE1.NAME,和<br>SELECT&nbsp;*&nbsp;FROM&nbsp;t_dup&nbsp;a&nbsp;WHERE&nbsp;a.ROWID&nbsp;&lt;&gt;&nbsp;(SELECT&nbsp;MIN(b.ROWID)&nbsp;FROM&nbsp;t_dup&nbsp;b&nbsp;WHERE&nbsp;a.code=b.code)<br>中a.code=b.code是一样的,SELECT&nbsp;MIN(b.ROWID)&nbsp;FROM&nbsp;t_dup&nbsp;b这个本身就变成B表了!<br>即A表和B表的关系!
 
SELECT&nbsp;*&nbsp;FROM&nbsp;t_dup&nbsp;a&nbsp;WHERE&nbsp;a.ROWID&nbsp;&lt;&gt;&nbsp;(SELECT&nbsp;MIN(b.ROWID)&nbsp;FROM&nbsp;t_dup&nbsp;b&nbsp;WHERE&nbsp;a.code=b.code)<br>这个是A,B表的关系,并不是自连接...<br>如果自连接不就变成t_dup.code&nbsp;=&nbsp;t_dup.code?只是嵌套查询罢了!
 
table1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>ID&nbsp;&nbsp;&nbsp;&nbsp;NAME&nbsp;&nbsp;&nbsp;SC&nbsp;<br>001&nbsp;&nbsp;&nbsp;AA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;88&nbsp;&nbsp;<br>001&nbsp;&nbsp;&nbsp;BB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;86&nbsp;&nbsp;&nbsp;<br>001&nbsp;&nbsp;&nbsp;CC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;78&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>001&nbsp;&nbsp;&nbsp;DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;68<br>002&nbsp;&nbsp;&nbsp;AA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;88<br>002&nbsp;&nbsp;&nbsp;AA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;85<br>SELECT&nbsp;*&nbsp;FROM&nbsp;TABLE1&nbsp;AS&nbsp;A&nbsp;WHERE&nbsp;A.ID&nbsp;NOT&nbsp;IN&nbsp;(SELECT&nbsp;MIN(ID)&nbsp;FROM&nbsp;TABLE1&nbsp;AS&nbsp;B&nbsp;WHERE&nbsp;A.NAME=B.NAME&nbsp;AND&nbsp;A.SC=B.SC);<br>002&nbsp;&nbsp;&nbsp;AA&nbsp;&nbsp;&nbsp;&nbsp;88<br>002&nbsp;&nbsp;&nbsp;AA&nbsp;&nbsp;&nbsp;&nbsp;85<br>--------------------------------------------------<br>发现LZ的方法在SQL&nbsp;SEVERE&nbsp;2000下可以用,唯一不是很完美的就是A.NAME=B.NAME&nbsp;AND&nbsp;A.SC=B.SC.....假设字段越多语句越长了...不知道会不会影响速度呢?
 
后退
顶部