我正在清理沒有主鍵的數據庫表(我知道,我知道,他們在想什麼?)。我無法添加主鍵,因爲列中有重複項,會成爲主鍵。重複值來自兩行在所有方面相同的行之一。我不能通過GUI刪除行(在本例中爲MySQL Workbench,但我正在尋找一種數據庫不可知的方法),因爲它拒絕在沒有主鍵(或至少一個UQ NN列)的表上執行任務,並且我無法添加主鍵,因爲列中有重複項,會成爲主鍵。重複值來自一個...如何刪除兩個完全相同的行之一?
如何刪除雙胞胎之一?
我正在清理沒有主鍵的數據庫表(我知道,我知道,他們在想什麼?)。我無法添加主鍵,因爲列中有重複項,會成爲主鍵。重複值來自兩行在所有方面相同的行之一。我不能通過GUI刪除行(在本例中爲MySQL Workbench,但我正在尋找一種數據庫不可知的方法),因爲它拒絕在沒有主鍵(或至少一個UQ NN列)的表上執行任務,並且我無法添加主鍵,因爲列中有重複項,會成爲主鍵。重複值來自一個...如何刪除兩個完全相同的行之一?
如何刪除雙胞胎之一?
一個選項來解決你的問題是創建一個新表具有相同的架構,然後執行:
INSERT INTO new_table (SELECT DISTINCT * FROM old_table)
,然後只需重命名錶。
您當然需要大約相同數量的空間,因爲您的磁盤需要備份磁盤才能完成此操作!
效率不高,但它非常簡單。
在我的情況下,我可能得到GUI給我一串問題行的值(或者,我可以這樣做手工)。在同事的建議下,在其債務我仍然,我用它來創建一個INSERT語句:
INSERT
'ID1219243408800307444663', '2004-01-20 10:20:55', 'INFORMATION', 'admin' (...)
INTO some_table;
我測試的INSERT語句,所以,我現在生下三胞胎。最後,我跑了一個簡單的DELETE鍵刪除所有的人......
DELETE FROM some_table WHERE logid = 'ID1219243408800307444663';
隨後的插入的一個更多的時間,讓我用一個單一的行,主鍵的明亮的可能性。
注意,MySQL有自己的擴展DELETE
,這是DELETE ... LIMIT
,這在平時的工作方式你會從LIMIT
期望:http://dev.mysql.com/doc/refman/5.0/en/delete.html
的MySQL特定LIMIT ROW_COUNT選項刪除告訴服務器 控制返回到 客戶端之前要刪除的最大行數。這可以用來確保給定的DELETE語句 不會花費太多時間。您可以簡單地重複DELETE 語句,直到受影響的行數小於LIMIT 值。
因此,你可以使用DELETE FROM some_table WHERE x="y" AND foo="bar" LIMIT 1;
請注意,有沒有一個簡單的方法,說「刪除一切,除了一個」 - 只是不停地檢查你是否還有一行重複。
的情況下,你可以像
ALTER TABLE yourtable ADD IDCOLUMN bigint NOT NULL IDENTITY (1, 1)
這麼做添加一列。
然後按您的問題列對計數行進行計數,其中count> 1,這將識別您的雙胞胎(或三胞胎或其他)。
然後選擇您的問題列,其內容等於上面標識的內容並檢查IDCOLUMN中的ID。
從您的表中刪除IDCOLUMN等於這些ID之一。
SET ROWCOUNT 1
DELETE FROM [table] WHERE ....
SET ROWCOUNT 0
這隻會刪除兩個相同的行
迄今爲止最簡單的解決方案..不需要重複的表或改變當前表像所有其他建議。 – woony 2015-06-25 12:15:53
更簡單會是'DELETE TOP 1 FROM ...'。如果使用SQL Server,以後還會更好:[備註 - 重要 - 使用SET ROWCOUNT不會影響DELETE,INSERT和UPD在未來版本的SQL Server中的ATE語句](https://technet.microsoft.com/en-us/library/ms188774.aspx) – ToolmakerSteve 2015-07-11 23:37:50
我添加了一個GUID列表中的一個,並設置它生成每行一個新的ID。然後我可以使用GUI刪除行。
刪除top(1)適用於Microsoft SQL Server(T-SQL)。
這可以通過使用CTE和ROW_NUMBER()
功能,以下來完成:
/* Sample Data */
CREATE TABLE #dupes (ID INT, DWCreated DATETIME2(3))
INSERT INTO #dupes (ID, DWCreated) SELECT 1, '2015-08-03 01:02:03.456'
INSERT INTO #dupes (ID, DWCreated) SELECT 2, '2014-08-03 01:02:03.456'
INSERT INTO #dupes (ID, DWCreated) SELECT 1, '2013-08-03 01:02:03.456'
/* Check sample data - returns three rows, with two rows for ID#1 */
SELECT * FROM #dupes
/* CTE to give each row that shares an ID a unique number */
;WITH toDelete AS
(
SELECT ID, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY DWCreated) AS RN
FROM #dupes
)
/* Delete any row that is not the first instance of an ID */
DELETE FROM toDelete WHERE RN > 1
/* Check the results: ID is now unique */
SELECT * FROM #dupes
/* Clean up */
DROP TABLE #dupes
有一列ORDER BY是很方便的,但沒有必要,除非你有一個偏好該行刪除。這也將處理重複記錄的所有實例,而不是一次強制刪除一行。
這裏最好的解決方案恕我直言。 :) – 2018-02-05 11:31:54
對於PostgreSQL,你可以這樣做:
DELETE FROM tablename
WHERE id IN (SELECT id
FROM (SELECT id, ROW_NUMBER()
OVER (partition BY column1, column2, column3 ORDER BY id) AS rnum
FROM tablename) t
WHERE t.rnum > 1);
列1,列2,欄3將列集具有重複的值。
參考here。
雖然這可能在理論上回答這個問題,[這將是更可取的](/ meta.stackoverflow.com/q/8259)在這裏包括答案的基本部分,並提供鏈接供參考。 – 2016-11-07 13:53:34
感謝您的提示,編輯我的答案:) – 2016-11-07 13:56:22
這是否仍然需要'id'是唯一的行之間? – Narfanator 2017-05-18 19:29:54
嘗試限制1?這隻會刪除符合您DELETE
查詢
DELETE FROM `table_name` WHERE `column_name`='value' LIMIT 1;
,該行1在PostgreSQL的有一個叫ctid
隱含列。請參閱wiki。所以,你可以自由地使用以下命令:
WITH cte1 as(
SELECT unique_column, max(ctid) as max_ctid
FROM table_1
GROUP BY unique_column
HAVING count(*) > 1
), cte2 as(
SELECT t.ctid as target_ctid
FROM table_1 t
JOIN cte1 USING(unique_column)
WHERE t.ctid != max_ctid
)
DELETE FROM table_1
WHERE ctid IN(SELECT target_ctid FROM cte2)
我不知道它是如何安全地使用這個時候有併發更新的可能性。所以人們可能會發現在實際進行清理之前製作一個LOCK TABLE table_1 IN ACCESS EXCLUSIVE MODE;
是明智的。
您可以使用最大值,這與我的情況相關。
DELETE FROM [table] where id in
(select max(id) from [table] group by id, col2, col3 having count(id) > 1)
務必首先測試您的結果,並在您的「擁有」條款中有一個限制條件。有了這麼大的刪除查詢,您可能需要先更新數據庫。
這適用於PostgreSQL的
DELETE FROM tablename WHERE id = 123 AND ctid IN (SELECT ctid FROM tablename WHERE id = 123 LIMIT 1)
這樣的重複有多少呢? – Alnitak 2013-05-08 12:12:09
@Alnitak在這個問題的原始上下文中,只有一兩個 - 我剛剛發現了另一個帶* loaded * duplciates的表,其中像http://stackoverflow.com/a/3777663/236081這樣的策略可能會更多適當的 – d3vid 2013-05-08 13:01:05