天天看點

SQL資料去重

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   peopleName in (select peopleName    from people group by peopleName      having count(peopleName) > 1)

and   peopleId not in (select min(peopleId) from people group by peopleName     having count(peopleName)>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)   

6.消除一個字段的左邊的第一位:

update tableName set [Title]=Right([Title],(len([Title])-1)) where Title like '村%'

7.消除一個字段的右邊的第一位:

update tableName set [Title]=left([Title],(len([Title])-1)) where Title like '%村'

8.假删除表中多餘的重複記錄(多個字段),不包含rowid最小的記錄

update vitae set ispass=-1

where peopleId in (select peopleId from vitae group by peopleId,seq having count(*) > 1) and seq in (select 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)

9、完全重複資料去重方法

  對于表中完全重複資料去重,可以采用以下SQL語句。

  Code

  CREATE TABLE"#temp"AS (SELECT DISTINCT * FROM 表名);--建立臨時表,并把DISTINCT 去重後的資料插入到臨時表中

  truncate TABLE 表名;--清空原表資料

  INSERT INTO 表名(SELECT * FROM"#temp");--将臨時表資料插入到原表中

  DROP TABLE"#temp";--删除臨時表

  具體思路是,首先建立一個臨時表,然後将DISTINCT之後的表資料插入到這個臨時表中;然後清空原表資料;再講臨時表中的資料插入到原表中;最後删除臨時表。

10、部分資料去重方法

  首先查找重複資料

  select 字段1,字段2,count(*) from 表名 groupby 字段1,字段2 having count(*) > 1

  将上面的>号改為=号就可以查詢出沒有重複的資料了。

  想要删除這些重複的資料,可以使用下面語句進行删除:

  deletefrom 表名 a where 字段1,字段2 in

  (select 字段1,字段2,count(*) from 表名 groupby 字段1,字段2 having count(*) > 1)

  上面的語句非常簡單,就是将查詢到的資料删除掉。不過這種删除執行的效率非常低,對于大資料量來說,可能會将資料庫卡死。

  基于上述情況,可以先将查詢到的重複的資料插入到一個臨時表中,然後對進行删除,這樣,執行删除的時候就不用再進行一次查詢了。如下:

  CREATETABLE 臨時表 AS

  (select 字段1,字段2,count(*) from 表名 groupby 字段1,字段2 having count(*) > 1)

  下面就可以進行這樣的删除操作了:

  deletefrom 表名 a where 字段1,字段2 in (select 字段1,字段2 from 臨時表);

  先建臨時表再進行删除的操作要比直接用一條語句進行删除要高效得多。

  上面的語句會把所有重複的全都删除,在oracle中,有個隐藏了自動rowid,裡面給每條記錄一個唯一的rowid,我們如果想保留最新的一條記錄,我們就可以利用這個字段,保留重複資料中rowid最大的一條記錄就可以了。

  下面是查詢重複資料的一個例子:

  select a.rowid,a.* from 表名 a

  where a.rowid !=

  (

  selectmax(b.rowid) from 表名 b

  where a.字段1 = b.字段1 and

  a.字段2 = b.字段2

  )

  上面括号中的語句是查詢出重複資料中rowid最大的一條記錄。而外面就是查詢出除了rowid最大之外的其他重複的資料了。

  由此,我們要删除重複資料,隻保留最新的一條資料,就可以這樣寫了:

  delete from 表名 a

  where a.rowid !=

  (

  select max(b.rowid) from 表名 b

  where a.字段1 = b.字段1 and

  a.字段2 = b.字段2

  )

  同理,上述代碼的執行效率畢竟低,是以我們可以考慮建立臨時表,将需要判斷重複的字段、rowid插入臨時表中,然後删除的時候在進行比較。

  create table 臨時表 as

  select a.字段1,a.字段2,MAX(a.ROWID) dataid from 正式表 a GROUPBY a.字段1,a.字段2;

  delete from 表名 a

  where a.rowid !=

  (

  select b.dataid from 臨時表 b

  where a.字段1 = b.字段1 and

  a.字段2 = b.字段2

  );

  commit;