我們先看一下相關(guān)數(shù)據(jù)結(jié)構(gòu)的知識(shí)。
在學(xué)習(xí)線性表的時(shí)候,曾有這樣一個(gè)例題。
已知一個(gè)存儲(chǔ)整數(shù)的順序表La,試構(gòu)造順序表Lb,要求順序表Lb中只包含順序表La中所有值不相同的數(shù)據(jù)元素。
算法思路:
先把順序表La的第一個(gè)元素付給順序表Lb,然后從順序表La的第2個(gè)元素起,每一個(gè)元素與順序表Lb中的每一個(gè)元素進(jìn)行比較,如果不相同,則把該元素附加到順序表Lb的末尾。
復(fù)制代碼 代碼如下:
public SeqListint> Purge(SeqListint> La)
{
SeqListint> Lb = new SeqListint>(La.Maxsize);
//將a表中的第1個(gè)數(shù)據(jù)元素賦給b表
Lb.Append(La[0]);
//依次處理a表中的數(shù)據(jù)元素
for (int i = 1; i = La.GetLength() - 1; ++i)
{
int j = 0;
//查看b表中有無與a表中相同的數(shù)據(jù)元素
for (j = 0; j = Lb.GetLength() - 1; ++j)
{
//有相同的數(shù)據(jù)元素
if (La[i].CompareTo(Lb[j]) == 0)
{
break;
}
}
//沒有相同的數(shù)據(jù)元素,將a表中的數(shù)據(jù)元素附加到b表的末尾。
if (j > Lb.GetLength() - 1)
{
Lb.Append(La[i]);
}
return Lb;
}
}
如果理解了這個(gè)思路,那么數(shù)據(jù)庫中的處理就好辦了。
我們可以做一個(gè)臨時(shí)表來解決問題
復(fù)制代碼 代碼如下:
select distinct * into #Tmp from tableName
drop table tableName
select * into tableName from #Tmp
drop table #Tmp
發(fā)生這種重復(fù)的原因是表設(shè)計(jì)不周產(chǎn)生的,增加唯一索引列即可解決。
但是你說了,我不想增加任何字段,但這時(shí)候又沒有顯式的標(biāo)識(shí)列,怎么取出標(biāo)識(shí)列呢?(可以是序號(hào)列,GUID,等)
上個(gè)問題先不講,先看看這個(gè)問題。
我們分別在三種數(shù)據(jù)庫中看一下處理辦法,就是通常我們用的Sqlserver2000,Sqlserver2005,Oracle 10g.
1. SQL Server 2000 構(gòu)造序號(hào)列
方法一:
SELECT 序號(hào)=
(SELECT COUNT(客戶編號(hào)) FROM 客戶 AS a WHERE a.客戶編號(hào)= b.客戶編號(hào)),
客戶編號(hào),公司名稱 FROM 客戶 AS b ORDER BY 1;
方法二:
SELECT 序號(hào)= COUNT(*),
a.客戶編號(hào), a.公司名稱FROM 客戶 AS a, 客戶 AS b
WHERE a.客戶編號(hào)>= b.客戶編號(hào) GROUP BY a.客戶編號(hào), b.公司名稱 ORDER BY 序號(hào);
2. SQL Server 2005 構(gòu)造序號(hào)列
方法一:
SELECT RANK() OVER (ORDER BY 客戶編號(hào) DESC) AS 序號(hào), 客戶編號(hào),公司名稱 FROM 客戶;
方法二:
WITH TABLE AS
(SELECT ROW_NUMBER() OVER (ORDER BY 客戶編號(hào) DESC) AS 序號(hào), 客戶編號(hào),公司名稱 FROM 客戶)
SELECT * FROM TABLE
WHERE 序號(hào) BETWEEN 1 AND 3;
3. Oracle 里 rowid 也可看做默認(rèn)標(biāo)識(shí)列
在Oracle中,每一條記錄都有一個(gè)rowid,rowid在整個(gè)數(shù)據(jù)庫中是唯一的,rowid確定了每條記錄是在Oracle中的哪一個(gè)數(shù)據(jù)文件、塊、行上。
在重復(fù)的記錄中,可能所有列的內(nèi)容都相同,但rowid不會(huì)相同,所以只要確定出重復(fù)記錄中那些具有最大rowid的就可以了,其余全部刪除。
復(fù)制代碼 代碼如下:
select * from test;select * from test group by id having count(*)>1select * from test group by idselect distinct * from testdelete from test a where a.rowid!=(select max(rowid) from test b where a.id=b.id);扯遠(yuǎn)了,回到原來的問題,除了采用數(shù)據(jù)結(jié)構(gòu)的思想來處理,因?yàn)閿?shù)據(jù)庫特有的事務(wù)處理,能夠把數(shù)據(jù)緩存在線程池里,這樣也相當(dāng)于臨時(shí)表的功能,所以,我們還可以用游標(biāo)來解決刪除重復(fù)記錄的問題。
declare @max int,
@id int
declare cur_rows cursor local for select id ,count(*) from test group by id having count(*) > 1
open cur_rows
fetch cur_rows into @id ,@max
while @@fetch_status=0
begin
select @max = @max -1
set rowcount @max --讓這個(gè)時(shí)候的行數(shù)等于少了一行的統(tǒng)計(jì)數(shù),想想看,為什么
delete from test where id = @id
fetch cur_rows into @id ,@max
end
close cur_rows
set rowcount 0 以上是閃電查閱一些資料寫出的想法,有考慮不周的地方,歡迎大家指出。
您可能感興趣的文章:- SQL語句實(shí)現(xiàn)刪除重復(fù)記錄并只保留一條
- MySQL數(shù)據(jù)庫中刪除重復(fù)記錄的方法總結(jié)[推薦]
- SqlServer2005中使用row_number()在一個(gè)查詢中刪除重復(fù)記錄的方法
- SQL Server2008中刪除重復(fù)記錄的方法分享
- sqlserver 刪除重復(fù)記錄處理(轉(zhuǎn))
- SqlServer 2005中使用row_number()在一個(gè)查詢中刪除重復(fù)記錄
- mysql刪除重復(fù)記錄語句的方法
- SQL語句實(shí)現(xiàn)刪除ACCESS重復(fù)記錄的兩種方法
- 有用的SQL語句(刪除重復(fù)記錄,收縮日志)
- sql 刪除表中的重復(fù)記錄