[MSSQL] CTE 的應用(2) - 從沒 PrimaryKey 的資料表中刪除多餘重複資料

[SQL] CTE 的應用(2) - 從沒 PrimaryKey 的資料表中刪除多餘重複資料

這個故事是發生在一個沒有建立 PrimaryKey的資料表上,很不巧的,剛好這個資料表是紀錄登入帳號的表,因為沒有 PK ,也沒有建立 Unique Index ,所以重複建立資料時,在讀取就發生悲劇了,以下模擬重複資料的情況:

 

-- Author: Henry
-- Author URL: http://www.dotblogs.com.tw/henryli/
-- Script Version: 1.0
-- MSSQL Version: 2005+
-- Create date: 2014-06-02
-- Update date: 2014-06-02
-- Description:	建立一個沒有 PrimaryKey的資料表,並寫入重複資料
-- Require: none
-- =============================================
--存在則刪除
IF OBJECT_ID('NoPrimaryKey') IS NOT NULL
	DROP TABLE NoPrimaryKey;
GO
--創建資料表
CREATE TABLE NoPrimaryKey
(
	ID INT NOT NULL,
	Name NVARCHAR(20) NOT NULL
);
--輸入測試資料
INSERT INTO NoPrimaryKey (ID, Name)
VALUES
	(1, 'OK'),
	(1, 'OK'),
	(2, 'OK');
--查詢
SELECT * FROM NoPrimaryKey;

 

查詢結果如下:

image

 

由於資料一樣,嘗試用下列語法刪除,都達不到我想只保留的一筆重複資料的效果

-- Author: Henry
-- Author URL: http://www.dotblogs.com.tw/henryli/
-- Script Version: 1.0
-- MSSQL Version: 2005+
-- Create date: 2014-06-02
-- Update date: 2014-06-02
-- Description:	嘗試刪除多餘重複資料,但沒有成功 (如果有 CTE 以外的語法能達到,還請各位大大提供)
-- Require: none
-- =============================================
--1.無法正確刪除多餘重複資料
DELETE FROM [dbo].[NoPrimaryKey] WHERE ID = 1;

--2.無法正確刪除多餘重複資料
DELETE FROM [dbo].[NoPrimaryKey]
WHERE ID IN (
	SELECT TOP 1 ID
	FROM [dbo].[NoPrimaryKey]
	WHERE ID = 1
);

 

打開編輯畫面直接對重複資料做刪除,也一樣出錯

 image

 

這時亮出 CTE ,可輕鬆解決現有的囧境。

-- Author: Henry
-- Author URL: http://www.dotblogs.com.tw/henryli/
-- Script Version: 1.0
-- MSSQL Version: 2005+
-- Create date: 2014-06-02
-- Update date: 2014-06-02
-- Description:	使用 CTE 刪除多餘的重複資料
-- Require: none
-- =============================================
;WITH NoRepeatData AS (
	SELECT ID, Name, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) AS RowNum
	FROM [dbo].[NoPrimaryKey]
)
DELETE FROM NoRepeatData
WHERE RowNum > 1;

--查詢
SELECT * FROM NoPrimaryKey;

 

資料正常。

 image

 

參考資料:

使用 TOP 來限制刪除的資料列

 

 

創用 CC 授權條款
本著作係採用創用 CC 姓名標示-相同方式分享 4.0 國際 授權條款授權,文章歡迎轉載,請註明出處,謝謝~~~