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
where T1.cnt>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不重複的結果集
更改數據庫中表的所屬用戶的兩個方法
大家可能會經常碰到一個數據庫備份還原到另外一臺機器結果導致所有的表都不能打開了,原因是建表的時候採用了當時的數據庫用戶……
========第四篇=========
如何查詢數據庫中的重複記錄?

比如說有個表中的數據是這樣:
---------
a
a
a
b
b
c
---------

查詢出的結果是:
記錄 數量
a 3
b 2
c 1

怎樣寫這個SQL語句?
-----------------------
select distinct(name),count(*) from tabname group by name;
-------------------------------------
想出來了,這樣就可以排序了。
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=&#39;#$#@%$@&#39; 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 a;

SELECT a.*, dlookup("r1","表2","id=" & a.id & " and name=&#39;"& a.name & "&#39;") AS r1, dlookup("r2","表2","id=" & a.id & " and name=&#39;"& a.name & "&#39;") AS r2
FROM [SELECT DISTINCT 表2.id, 表2.NAME
FROM 表2]. AS a;

注意,上述代碼中由於沒有唯一標識列,因此顯示的 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字段包含重複值;

Id
A B
C D
1
11 a
34 bvb
2
22 a
35 fgfg
3
33 d
ht sdf
4
44 a
345 de
5
55 c
sfsf sscv
6
66 b
rt 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)

這樣就得到我們想要的結果集了:
Id
A B
C D
1
11 a
34 bvb
3
33 d
ht sdf
5
55 c
sfsf sscv
6
66 b
rt 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 b

distinct怎麼沒起作用?作用是起了的,不過他同時作用了兩個字段,也就是必須得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 name
select * from table group by name


========第十一篇=========
查詢及刪除重複記錄的方法
(一)
1、查找表中多餘的重複記錄,重複記錄是根據單個字段(peopleId)來判斷
select * from people
where 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 a
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)

4、刪除表中多餘的重複記錄(多個字段),只留有rowid最小的記錄
delete from vitae a
where (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 a
where (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 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

  就可以得到無重複記錄的結果集。

  如果該表需要刪除重複的記錄(重複記錄保留1條),可以按以下方法刪除

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不重複的結果集(但多了一個autoID字段,實際寫時可以寫在select子句中省去此列)

(四)
查詢重複

select * from tablename where id in (

select id from tablename

group by id

having count(id) > 1

)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章