你要這樣也可以
1.先備份, 以防萬一
2.根據原本的Table的結構建立一個暫存用的Table, 但是要有PK欄位, 這樣才能夠篩選掉重複的
3.從原本的Table, select 出資料 insert 到暫存用的Table
4.先清空原本的Table, 再從暫存用的Table, select 出資料 insert 到原本用的Table
5.刪除暫存用的Table
何謂 "刪除重複資料"?
目前資料表的結構長怎麼樣?
id title url
1 yahoo yahoo.com.tw
2 yahoo yahoo.com.tw
3 google google.com
這是一個table,id是pk,1,2重複,所以1,2可不可以變成一筆資料
若RANK >2 DELETE
PARTITION BY PKey的欄位
SELECT A.* , RANK() OVER(PARTITION BY B.CId ORDER BY B.score DESC) AS RANK
FROM 資料表 A
--這邊先確認是否RANK2以上為重複資料
SELECT A.* , RANK() OVER(PARTITION BY B.CId ORDER BY B.score DESC) AS RANK
INTO #TEMPTABLE
FROM 資料表 A
WHERE RANK=1
#TEMPTABLE 暫存檔內就是你沒有重複的資料
看你要如何處理
刪除原本TABLE 把TEMPTABLE倒進去
或是另外新建一個TABLE_B 把暫存檔倒入也可(較保險)
--ROW_NUMBER 每一筆資料照順序編號 1 2 3 4 5 6
一行指令即可。
DELETE
FROM
abc
WHERE
find_in_set(id,(SELECT group_concat( id ) FROM abc GROUP BY title HAVING count(*)> 1))
and not id in (select max(id) from abc group by title)
是沒錯,但語法精簡,
不過,若沒有full table scan,要如何判斷有沒有重覆?
其實,這個問題,根本不應該發生,
既然不許重覆,那麼,在 insert 之前,就該搞定了,
怎麼可以讓它進檔,再事後去刪?
這裡的index 關鍵是在 gruoup by 那邊啦,find_in_set() 那裡是id.各種指令與函數,都有其用處,要靈活搭配使用,沒有絕對.
網路上有一些不是真的懂的,卻又愛寫一堆,哪種語法不要用的,那些不要太相信.現在還是有一堆自稱架構師,說什麼不要用stored procedure的,這種傻話從上個世紀就有了.可是Oracle還是一樣有PL/SQL,
Postgresql 還一直增加各種 PL/XXX, 最近正在弄 PL/Julia了.
每隔一段時間,就看到一些各種簡化原則的,像這篇
零基礎快速自學SQL,2天足矣!
沒多久變成 零基礎快速自學SQL,1天足矣
都是同一家的,期待她可以精進,看何時進步到一小時學會.
裡面還有鏈結到一篇 20條Tips:高性能SQL查詢,優化取數速度方案 這系列超有意思,是大陸一堆複製貼上的,原本是一個30條Tips.30 Tips又是從很早以前,現在已經過時的,抄出來的,但是抄的時候,又有一些地方抄錯,最終變成20Tips 最多複製貼上.看著
以前錯誤那篇,現在經過十幾年,小孩都要唸大學了.
還有一些自稱XXX學院,或是各種在教學的,不夠深入但是卻很愛講的,
就把一些不完全正確的觀念,簡化成幾個原則,到處傳播.
【幾何無王者之道!】
我不太相信什麼速成之說。
一般來說,將想要的資料建立到新表上是最安全的做法。
至少你的原始資料不會被變動到,出問題了都還可以救。
當然,如果你想要直接動原始表刪除也並非不是沒有命令。
只是還是有一定的危險性。
再動作之前得先備份好。免得指令下去了錯誤想後悔也來不及了。
基本上,我並不建議你直接對原資料表做動作。
還是乖乖的用原來的方式才是比較安全的做法。