我想刪除表中的重複記錄,而不使用臨時表它怎麼可能?查詢從表中刪除重複記錄而不使用臨時表?
回答
- 做一個查詢,讓你有資格作爲複製
- 進行查詢B中得到你想要保持
- 進行查詢的行是刪除有能力的所有行的行但不在B.
例子。
假設一個名爲table
的表,其中包含一個名爲id
的自動增量ID列和一個名爲name
的列,您要刪除其中的雙打。在每個名稱中,您希望保留最早的記錄(ID最低的那個)。
查詢則看起來像:
SELECT * FROM table
WHERE name IN (SELECT name FROM table GROUP BY name HAVING COUNT(*) > 1)
查詢B.將:
SELECT * FROM table
WHERE id IN (SELECT min(id) FROM table GROUP BY name)
現在將這些形成刪除查詢:
DELETE FROM table
WHERE name IN (SELECT name FROM table GROUP BY name HAVING COUNT(*) > 1)
AND NOT id IN (SELECT min(id) FROM table GROUP BY name)
在這個例子中,在你可以忽略第一個查詢,但是當事情變得更復雜時,這是一個很好的額外保障措施。
你不行。 完全重複記錄(每個字段相同的記錄)不能一個刪除,因爲在刪除查詢中,您不能在Where
子句中區分它們。
唯一的辦法是做一個select distinct
查詢來選擇沒有重複的所有行,然後將它們插入一個空的表中。
如果您沒有完全重複的記錄,那麼問題的解釋不正確,並且您不希望刪除重複記錄,因爲沒有任何記錄。具有不完整的相同字段的行不重複。在這種情況下,您希望刪除具有相同字段的行,在這種情況下,如果某個字段或字段集不相同,則必須指定要離開的行。
我不認爲這是真的。假設你從一個表中選擇了全部,再加上一個ROW_NUMBER()列。這些行將以聚簇索引順序返回,並且您將爲每個行獲取不同的行號值。然後您可以使用它來區分WHERE子句中的重複項。 – Yellowfog 2010-08-07 19:07:30
row_number是一個與order by語句一起使用的函數,只能在select查詢中使用。這只是row_number不能直接參與delete語句的原因之一。我在互聯網上找到的解決方案之一是創建一個單獨的表,將row_number作爲新字段引入,然後執行刪除語句。這不是作者想要的。 – AlexanderMP 2010-08-07 22:03:48
通過使用公用表表達式(CTE),您可以毫無問題地完成此任務,而無需使用任何臨時表。如果刪除是針對高流量表,請注意。刪除大量的數據可能會導致鎖定和阻塞,同時會傳輸轉錄。
注意:此代碼沒有進行任何測試,但應該可以工作(SQL 2005及更高版本)。
/* Create test data with duplicates */
declare @TestTable Table (Col1 int)
insert into @TestTable
select 1 union all
select 1 union all
select 2 union all
select 3 union all
select 3 union all
select 4
;
/* Create CTE to number all duplicates (gives a running number to all identical values in Col1) */
with FindDupes as
(
Select Col1,ROW_NUMBER() over (partition by Col1 order by Col1) RN
from @TestTable
)
/* Delete the duplicates (anything that has a higher rownumber than one) */
Delete from FindDupes where RN>1
;
/* Select the remaining data from the table */
Select * from @TestTable
我覺得這個查詢將正常工作:
delete from table where id in (select count(*)c from table group by id having c > 1)
模式,請... – JNK 2010-08-07 10:58:19
爲什麼不使用臨時表?或者,'聲明@itemsToRemove表(...)' – tenfour 2010-08-07 11:04:57