วิธีลบแถวที่ซ้ำกันใน SQL Server


415

ฉันจะลบแถวที่ซ้ำกันที่ไม่มีunique row idอยู่ได้อย่างไร

โต๊ะของฉันคือ

col1  col2 col3 col4 col5 col6 col7
john  1    1    1    1    1    1 
john  1    1    1    1    1    1
sally 2    2    2    2    2    2
sally 2    2    2    2    2    2

ฉันต้องการที่จะเหลือต่อไปนี้หลังจากการลบที่ซ้ำกัน:

john  1    1    1    1    1    1
sally 2    2    2    2    2    2

ฉันได้ลองใช้แบบสอบถามสองสามข้อ แต่ฉันคิดว่าพวกเขาขึ้นอยู่กับการมีรหัสแถวเนื่องจากฉันไม่ได้ผลลัพธ์ ตัวอย่างเช่น:

DELETE
FROM table
WHERE col1 IN (
    SELECT id
    FROM table
    GROUP BY id
    HAVING (COUNT(col1) > 1)
)

5
นี่ไม่ใช่การล่อลวงของลิงก์แรก ในคำถามนี้ไม่มี ID แถวและในคำถามที่เชื่อมโยงจะมี ID แถว แตกต่างกันมาก
เทคโนโลยีของคนต่างด้าว

เปลี่ยน 'SELECT id จากกลุ่มตาราง BY id HAVING' เพื่อให้มีฟังก์ชั่นรวมเช่น MAX / MIN และควรทำงาน
messed-up

คำตอบ:


785

ฉันชอบ CTEs และROW_NUMBERขณะที่ทั้งสองร่วมกันช่วยให้เราสามารถดูแถวที่จะลบ (หรือปรับปรุง) ดังนั้นเพียงแค่เปลี่ยนDELETE FROM CTE...ไปSELECT * FROM CTE:

WITH CTE AS(
   SELECT [col1], [col2], [col3], [col4], [col5], [col6], [col7],
       RN = ROW_NUMBER()OVER(PARTITION BY col1 ORDER BY col1)
   FROM dbo.Table1
)
DELETE FROM CTE WHERE RN > 1

DEMO (ผลลัพธ์แตกต่างกันฉันถือว่าเป็นเพราะพิมพ์ผิดในส่วนของคุณ

COL1    COL2    COL3    COL4    COL5    COL6    COL7
john    1        1       1       1       1       1
sally   2        2       2       2       2       2

ตัวอย่างนี้จะกำหนดรายการที่ซ้ำกันโดยคอลัมน์เดียวเพราะcol1 PARTITION BY col1หากคุณต้องการรวมหลายคอลัมน์เพียงแค่เพิ่มลงในPARTITION BY:

ROW_NUMBER()OVER(PARTITION BY Col1, Col2, ... ORDER BY OrderColumn)

2
ขอบคุณสำหรับคำตอบที่ดี MSFT ในทางตรงกันข้ามมีคำตอบที่ซับซ้อนมากที่นี่: stackoverflow.com/questions/18390574/…
Barka

2
@ omachu23: ในกรณีนี้มันไม่สำคัญแม้ว่าฉันคิดว่า CTE มีประสิทธิภาพมากกว่าข้างนอก ( AND COl1='John') โดยปกติคุณควรใช้ตัวกรองใน CTE
Tim Schmelter

1
@ omachu23: คุณสามารถใช้ SQL ใด ๆ ใน CTE (นอกเหนือจากการสั่งซื้อ) ...FROM dbo.Table1 WHERE Col1='John'ดังนั้นถ้าคุณต้องการที่จะกรองโดยจอห์นส์: นี่คือซอ: sqlfiddle.com/#!6/fae73/744/0
Tim Schmelter

1
วิธีแก้ปัญหาที่ง่ายที่สุดอาจset rowcount 1 delete from t1 where col1=1 and col2=1เห็นได้ที่นี่
Zorgarath

15
คำตอบนี้จะลบแถวที่ซ้ำกันใน col1 เท่านั้น เพิ่มคอลัมน์ใน "เลือก" เป็น "พาร์ทิชันโดย" ตัวอย่างเช่นการใช้การเลือกในคำตอบ: RN = ROW_NUMBER () ขึ้นไป (พาร์ทิชันโดย col1, col2, col3, col4, col5, col6, col7, OR7 BY col1)
rlee

158

ฉันต้องการ CTE สำหรับการลบแถวที่ซ้ำกันออกจากตารางเซิร์ฟเวอร์ sql

ขอแนะนำให้ติดตามบทความนี้: http://codaffection.com/sql-server-article/delete-duplicate-rows-in-sql-server/

โดยการรักษาต้นฉบับ

WITH CTE AS
(
SELECT *,ROW_NUMBER() OVER (PARTITION BY col1,col2,col3 ORDER BY col1,col2,col3) AS RN
FROM MyTable
)

DELETE FROM CTE WHERE RN<>1

โดยไม่ต้องรักษาต้นฉบับ

WITH CTE AS
(SELECT *,R=RANK() OVER (ORDER BY col1,col2,col3)
FROM MyTable)
 
DELETE CTE
WHERE R IN (SELECT R FROM CTE GROUP BY R HAVING COUNT(*)>1)

2
ฟังก์ชั่น Windowing เป็นทางออกที่ดี
Robert Casey

2
ฉันสับสนเล็กน้อย คุณลบออกจาก CTE ไม่ใช่ตารางต้นฉบับ แล้วมันทำงานอย่างไร
Bigeyes

8
@Bigeyes การลบเร็กคอร์ดจาก CTE จะลบเร็กคอร์ดที่สอดคล้องกันออกจากตารางฟิสิคัลจริง (เนื่องจาก CTE มีการอ้างอิงกับเร็กคอร์ดจริง)
Shamseer K

ฉันไม่รู้ว่ามันเป็นอย่างนั้นจนกระทั่งโพสต์นี้ ... ขอบคุณ
Zakk Diaz

1
ทำไมคุณต้องการลบทั้งต้นฉบับและสำเนา ฉันไม่เข้าใจว่าทำไมคุณไม่ต้องการลบสำเนาที่ซ้ำกันและเก็บไว้อีก
รวย

52

โดยไม่ต้องใช้CTEและROW_NUMBER()คุณสามารถลบระเบียนเพียงแค่ใช้กลุ่มโดยด้วยMAXฟังก์ชันที่นี่เป็นตัวอย่าง

DELETE
FROM MyDuplicateTable
WHERE ID NOT IN
(
SELECT MAX(ID)
FROM MyDuplicateTable
GROUP BY DuplicateColumn1, DuplicateColumn2, DuplicateColumn3)

4
แบบสอบถามนี้จะลบระเบียนที่ไม่ซ้ำกัน
Derek Smalls

8
มันใช้งานได้ดีขอบคุณ @DerekSmall นี้ไม่ได้ลบระเบียนที่ไม่ซ้ำกันของฉัน
monteirobrena

1
หรือคุณสามารถเก็บบันทึกต้นฉบับโดยใช้MIN(ID)
Savage

18
DELETE from search
where id not in (
   select min(id) from search
   group by url
   having count(*)=1

   union

   SELECT min(id) FROM search
   group by url
   having count(*) > 1
)

คุณไม่สามารถเขียนซ้ำไปที่: ที่ไหน ID ใน (เลือกสูงสุด (id) ... มีจำนวน (*)> 1)?
เบรนต์

1
ฉันไม่เชื่อว่ามีความจำเป็นต้องใช้การมีหรือรวมกันสิ่งนี้จะพอเพียง: ลบออกจากการค้นหาโดยที่ id ไม่ได้อยู่ใน (เลือก min (id) จากกลุ่มการค้นหาโดย url)
Christopher Yang

9

โปรดดูวิธีการลบด้านล่างด้วย

Declare @table table
(col1 varchar(10),col2 int,col3 int, col4 int, col5 int, col6 int, col7 int)
Insert into @table values 
('john',1,1,1,1,1,1),
('john',1,1,1,1,1,1),
('sally',2,2,2,2,2,2),
('sally',2,2,2,2,2,2)

สร้างตารางตัวอย่างชื่อ@tableและโหลดด้วยข้อมูลที่กำหนด

ป้อนคำอธิบายรูปภาพที่นี่

Delete  aliasName from (
Select  *,
        ROW_NUMBER() over (Partition by col1,col2,col3,col4,col5,col6,col7 order by col1) as rowNumber
From    @table) aliasName 
Where   rowNumber > 1

Select * from @table

ป้อนคำอธิบายรูปภาพที่นี่

หมายเหตุ: หากคุณกำลังให้คอลัมน์ทั้งหมดในPartition byส่วนนั้นorder byมีความสำคัญไม่มาก

ฉันรู้ว่าคำถามนี้ถูกถามเมื่อสามปีที่แล้วและคำตอบของฉันคือรุ่นที่ Tim โพสต์อีกครั้ง แต่การโพสต์ในกรณีที่มีประโยชน์สำหรับทุกคน


9

หากคุณไม่มีการอ้างอิงเช่นคีย์ต่างประเทศคุณสามารถทำได้ ฉันทำมันมากเมื่อทดสอบการพิสูจน์แนวคิดและข้อมูลการทดสอบได้รับการทำซ้ำ

SELECT DISTINCT [col1],[col2],[col3],[col4],[col5],[col6],[col7]

INTO [newTable]

เข้าไปในวัตถุสำรวจและลบตารางเก่า

เปลี่ยนชื่อตารางใหม่ด้วยชื่อของตารางเก่า


นี่เป็นวิธีที่ง่ายที่สุดที่ฉันเรียนรู้ในเนื้อหาแนะนำและที่ฉันใช้
eric

7

Microsoft มีคำแนะนำที่เป็นระเบียบเรียบร้อยเกี่ยวกับวิธีลบรายการที่ซ้ำกัน ตรวจสอบ http://support.microsoft.com/kb/139444

โดยย่อนี่เป็นวิธีที่ง่ายที่สุดในการลบข้อมูลที่ซ้ำกันเมื่อคุณมีไม่กี่แถวที่จะลบ:

SET rowcount 1;
DELETE FROM t1 WHERE myprimarykey=1;

myprimarykeyเป็นตัวระบุสำหรับแถว

ฉันตั้งค่าrowcountเป็น 1 เพราะฉันมีเพียงสองแถวที่ทำซ้ำ หากฉันมีการทำซ้ำแถว 3 แถวฉันจะตั้งค่าrowcountเป็น 2 เพื่อให้ลบสองแถวแรกที่เห็นและทิ้งเฉพาะหนึ่งในตาราง t1

หวังว่ามันจะช่วยให้ทุกคน


1
ฉันจะรู้ได้อย่างไรว่าฉันซ้ำแถวกี่แถวถ้าฉันมี 10k แถว
Fearghal

@Fearghal ลอง "เลือก primaryKey นับ (*) จากกลุ่ม myTable โดย primaryKey;"
oabarca

1
แต่จะเกิดอะไรขึ้นถ้ามีจำนวนแถวที่ซ้ำกันต่างกัน เช่นแถวมี 2 ระเบียนและแถว B มี 5 ระเบียนและแถวคไม่มีระเบียนที่ซ้ำกัน
ไม

1
@ user2070775 จะเกิดอะไรขึ้นถ้าเฉพาะส่วนย่อยของแถวทั้งหมดมีการทำซ้ำและบางส่วนที่ซ้ำกันจะถูกทำซ้ำสองครั้งและสามหรือสี่ครั้ง
thermite

@ user2070775 ฉันพลาดส่วนที่คุณพูดว่า "เพียงไม่กี่แถวที่จะลบ" นอกจากนี้ยังมีคำเตือนในหน้าเกี่ยวกับการตั้งค่า rowcount ว่าในรุ่นอนาคตของ sql มันจะไม่ส่งผลกระทบต่อการปรับปรุงหรือลบคำสั่ง
thermite


4

หลังจากลองใช้วิธีแก้ปัญหาที่แนะนำข้างต้นแล้วมันก็ใช้ได้กับโต๊ะขนาดกลางเล็ก ๆ ฉันสามารถแนะนำวิธีแก้ปัญหาสำหรับตารางที่มีขนาดใหญ่มาก เนื่องจากมันทำงานซ้ำ

  1. ปล่อยมุมมองการพึ่งพาทั้งหมดของ LargeSourceTable
  2. คุณสามารถค้นหาการพึ่งพาโดยใช้สตูดิโอจัดการ sql คลิกขวาบนโต๊ะและคลิก "ดูการพึ่งพา"
  3. เปลี่ยนชื่อตาราง:
  4. sp_rename 'LargeSourceTable', 'LargeSourceTable_Temp'; GO
  5. สร้างLargeSourceTableอีกครั้ง แต่ตอนนี้เพิ่มคีย์หลักที่มีคอลัมน์ทั้งหมดที่กำหนดการทำซ้ำเพิ่มWITH (IGNORE_DUP_KEY = ON)
  6. ตัวอย่างเช่น:

    CREATE TABLE [dbo].[LargeSourceTable] ( ID int IDENTITY(1,1), [CreateDate] DATETIME CONSTRAINT [DF_LargeSourceTable_CreateDate] DEFAULT (getdate()) NOT NULL, [Column1] CHAR (36) NOT NULL, [Column2] NVARCHAR (100) NOT NULL, [Column3] CHAR (36) NOT NULL, PRIMARY KEY (Column1, Column2) WITH (IGNORE_DUP_KEY = ON) ); GO

  7. สร้างอีกครั้งมุมมองที่คุณลดลงในสถานที่แรกสำหรับตารางที่สร้างขึ้นใหม่

  8. ตอนนี้เรียกใช้สคริปต์ sql ต่อไปนี้คุณจะเห็นผลลัพธ์ใน 1,000,000 แถวต่อหน้าคุณสามารถเปลี่ยนหมายเลขแถวต่อหน้าเพื่อดูผลลัพธ์ได้บ่อยขึ้น

  9. โปรดทราบว่าฉันตั้งค่าการIDENTITY_INSERTเปิดและปิดเพราะหนึ่งคอลัมน์มีรหัสที่เพิ่มขึ้นอัตโนมัติซึ่งฉันก็คัดลอก

SET IDENTITY_INSERT LargeSourceTable ON DECLARE @PageNumber AS INT, @RowspPage AS INT DECLARE @TotalRows AS INT declare @dt varchar(19) SET @PageNumber = 0 SET @RowspPage = 1000000 select @TotalRows = count (*) from LargeSourceTable_TEMP

While ((@PageNumber - 1) * @RowspPage < @TotalRows )
Begin
    begin transaction tran_inner
        ; with cte as
        (
            SELECT * FROM LargeSourceTable_TEMP ORDER BY ID
            OFFSET ((@PageNumber) * @RowspPage) ROWS
            FETCH NEXT @RowspPage ROWS ONLY
        )

        INSERT INTO LargeSourceTable 
        (
             ID                     
            ,[CreateDate]       
            ,[Column1]   
            ,[Column2] 
            ,[Column3]       
        )       
        select 
             ID                     
            ,[CreateDate]       
            ,[Column1]   
            ,[Column2] 
            ,[Column3]       
        from cte

    commit transaction tran_inner

    PRINT 'Page: ' + convert(varchar(10), @PageNumber)
    PRINT 'Transfered: ' + convert(varchar(20), @PageNumber * @RowspPage)
    PRINT 'Of: ' + convert(varchar(20), @TotalRows)

    SELECT @dt = convert(varchar(19), getdate(), 121)
    RAISERROR('Inserted on: %s', 0, 1, @dt) WITH NOWAIT
    SET @PageNumber = @PageNumber + 1
End

SET IDENTITY_INSERT LargeSourceTable OFF


4

มีสองวิธีในmysql:

A)ลบแถวที่ซ้ำกันโดยใช้DELETE JOINคำสั่ง

DELETE t1 FROM contacts t1
INNER JOIN contacts t2 
WHERE 
    t1.id < t2.id AND 
    t1.email = t2.email;

แบบสอบถามนี้อ้างอิงตารางรายชื่อครั้งที่สองจึงใช้นามแฝงตารางและt1t2

ผลลัพธ์คือ:

1 การค้นหาตกลงได้รับผลกระทบ 4 แถว (0.10 วินาที)

ในกรณีที่คุณต้องการลบแถวที่ซ้ำกันและเก็บไว้lowest idคุณสามารถใช้คำสั่งต่อไปนี้:

DELETE c1 FROM contacts c1
INNER JOIN contacts c2 
WHERE
    c1.id > c2.id AND 
    c1.email = c2.email;

   

B)ลบแถวที่ซ้ำกันโดยใช้ตารางกลาง

ต่อไปนี้แสดงขั้นตอนสำหรับการลบแถวที่ซ้ำกันโดยใช้ตารางกลาง:

    1. สร้างตารางใหม่ที่มีโครงสร้างเหมือนกับตารางต้นฉบับที่คุณต้องการลบแถวที่ซ้ำกัน

    2. แทรกแถวที่แตกต่างจากตารางต้นฉบับไปยังตารางทันที

    3. แทรกแถวที่แตกต่างจากตารางต้นฉบับไปยังตารางทันที

 

ขั้นตอน 1. สร้างตารางใหม่ที่มีโครงสร้างเหมือนกับตารางต้นฉบับ:

CREATE TABLE source_copy LIKE source;

ขั้นตอนที่ 2 แทรกแถวที่แตกต่างจากตารางต้นฉบับไปยังตารางใหม่:

INSERT INTO source_copy
SELECT * FROM source
GROUP BY col; -- column that has duplicate values

ขั้นตอนที่ 3 วางตารางต้นฉบับและเปลี่ยนชื่อตารางทันทีเป็นแบบดั้งเดิม

DROP TABLE source;
ALTER TABLE source_copy RENAME TO source;

ที่มา: http://www.mysqltutorial.org/mysql-delete-duplicate-rows/


2
-- this query will keep only one instance of a duplicate record.
;WITH cte
     AS (SELECT ROW_NUMBER() OVER (PARTITION BY col1, col2, col3-- based on what? --can be multiple columns
                                       ORDER BY ( SELECT 0)) RN
         FROM   Mytable)



delete  FROM cte
WHERE  RN > 1

2

คุณต้องจัดกลุ่มตามระเบียนที่ซ้ำกันตามฟิลด์จากนั้นเก็บระเบียนหนึ่งรายการแล้วลบส่วนที่เหลือ ตัวอย่างเช่น:

DELETE prg.Person WHERE Id IN (
SELECT dublicateRow.Id FROM
(
select MIN(Id) MinId, NationalCode
 from  prg.Person group by NationalCode  having count(NationalCode ) > 1
 ) GroupSelect
 JOIN  prg.Person dublicateRow ON dublicateRow.NationalCode = GroupSelect.NationalCode 
 WHERE dublicateRow.Id <> GroupSelect.MinId)

2

การลบข้อมูลซ้ำออกจากตารางขนาดใหญ่ (หลายล้านระเบียน) อาจใช้เวลานาน ฉันขอแนะนำให้คุณแทรกจำนวนมากลงในตารางชั่วคราวของแถวที่เลือกแทนที่จะลบ

--REWRITING YOUR CODE(TAKE NOTE OF THE 3RD LINE) WITH CTE AS(SELECT NAME,ROW_NUMBER() 
OVER (PARTITION BY NAME ORDER BY NAME) ID FROM @TB) SELECT * INTO #unique_records FROM 
CTE WHERE ID =1;

2

สามารถทำได้หลายวิธีในเซิร์ฟเวอร์ sql วิธีที่ง่ายที่สุดคือ: แทรกแถวที่แตกต่างจากตารางแถวที่ซ้ำกันไปยังตารางชั่วคราวใหม่ จากนั้นลบข้อมูลทั้งหมดจากตารางแถวที่ซ้ำกันจากนั้นแทรกข้อมูลทั้งหมดจากตารางชั่วคราวซึ่งไม่มีข้อมูลซ้ำดังที่แสดงด้านล่าง

select distinct * into #tmp From table
   delete from table
   insert into table
   select * from #tmp drop table #tmp

   select * from table

ลบแถวที่ซ้ำกันโดยใช้ Common Table Expression (CTE)

With CTE_Duplicates as 
(select id,name , row_number() 
over(partition by id,name order by id,name ) rownumber  from table  ) 
delete from CTE_Duplicates where rownumber!=1


1

มีการอ้างอิงถึง https://support.microsoft.com/en-us/help/139444/how-to-remove-duplicate-rows-from-a-table-in-sql-server

ความคิดในการลบซ้ำเกี่ยวข้องกับ

  • a) การปกป้องแถวเหล่านั้นที่ไม่ซ้ำกัน
  • b) เก็บหนึ่งในหลาย ๆ แถวที่มีคุณสมบัติเข้าด้วยกันเป็นสำเนา

เป็นขั้นเป็นตอน

  • 1) ระบุแถวที่ตรงกับคำจำกัดความของการทำซ้ำและแทรกลงในตาราง temp พูด #tableAll
  • 2) เลือกไม่ซ้ำกัน (แถวเดียว) หรือแถวที่แตกต่างกันลงในตารางชั่วคราวพูด #tableUnique
  • 3) ลบออกจากตารางต้นฉบับเข้าร่วม #tableAll เพื่อลบรายการซ้ำ
  • 4) แทรกลงในตารางต้นฉบับแถวทั้งหมดจาก #tableUnique
  • 5) วาง #tableAll และ #tableUnique

1

หากคุณมีความสามารถในการเพิ่มคอลัมน์ลงในตารางชั่วคราวนี่เป็นวิธีแก้ปัญหาที่เหมาะกับฉัน:

ALTER TABLE dbo.DUPPEDTABLE ADD RowID INT NOT NULL IDENTITY(1,1)

จากนั้นดำเนินการลบโดยใช้การรวม MIN และ GROUP BY

DELETE b
FROM dbo.DUPPEDTABLE b
WHERE b.RowID NOT IN (
                     SELECT MIN(RowID) AS RowID
                     FROM dbo.DUPPEDTABLE a WITH (NOLOCK)
                     GROUP BY a.ITEM_NUMBER,
                              a.CHARACTERISTIC,
                              a.INTVALUE,
                              a.FLOATVALUE,
                              a.STRINGVALUE
                 );

ตรวจสอบว่า DELETE ดำเนินการอย่างถูกต้อง:

SELECT a.ITEM_NUMBER,
    a.CHARACTERISTIC,
    a.INTVALUE,
    a.FLOATVALUE,
    a.STRINGVALUE, COUNT(*)--MIN(RowID) AS RowID
FROM dbo.DUPPEDTABLE a WITH (NOLOCK)
GROUP BY a.ITEM_NUMBER,
    a.CHARACTERISTIC,
    a.INTVALUE,
    a.FLOATVALUE,
    a.STRINGVALUE
ORDER BY COUNT(*) DESC 

ผลลัพธ์ควรไม่มีแถวที่มีจำนวนมากกว่า 1 ในที่สุดลบคอลัมน์ rowid:

ALTER TABLE dbo.DUPPEDTABLE DROP COLUMN RowID;

0

อีกวิธีหนึ่งในการลบแถวที่แบ่งใช้โดยไม่ปล่อยข้อมูลออกในขั้นตอนเดียวมีดังต่อไปนี้:

delete from dublicated_table t1 (nolock)
join (
    select t2.dublicated_field
    , min(len(t2.field_kept)) as min_field_kept
    from dublicated_table t2 (nolock)
    group by t2.dublicated_field having COUNT(*)>1
) t3 
on t1.dublicated_field=t3.dublicated_field 
    and len(t1.field_kept)=t3.min_field_kept

0

โอ้ว้าวฉันรู้สึกงี่เง่ามากเมื่อพร้อมคำตอบทั้งหมดนี้พวกเขาเหมือนคำตอบของผู้เชี่ยวชาญกับ CTE และ temp table และอื่น ๆ

และสิ่งที่ฉันทำเพื่อให้มันทำงานได้ก็แค่รวมคอลัมน์ ID โดยใช้ MAX

DELETE FROM table WHERE col1 IN (
    SELECT MAX(id) FROM table GROUP BY id HAVING ( COUNT(col1) > 1 )
)

หมายเหตุ: คุณอาจต้องเรียกใช้หลายครั้งเพื่อลบสำเนาเนื่องจากจะเป็นการลบแถวที่ซ้ำกันหนึ่งชุดในแต่ละครั้ง


สิ่งนี้จะไม่ทำงานเนื่องจากจะลบรายการซ้ำทั้งหมดโดยไม่ทิ้งต้นฉบับ OP ขอให้เก็บรักษาบันทึกดั้งเดิม
0xdd

2
ไม่จริงจำนวนสูงสุดจะให้ ID สูงสุดที่ตรงตามเงื่อนไข หากไม่เป็นจริงให้พิสูจน์กรณีของคุณสำหรับการลงคะแนน
messed-up

0
DECLARE @TB TABLE(NAME VARCHAR(100));
INSERT INTO @TB VALUES ('Red'),('Red'),('Green'),('Blue'),('White'),('White')
--**Delete by Rank**
;WITH CTE AS(SELECT NAME,DENSE_RANK() OVER (PARTITION BY NAME ORDER BY NEWID()) ID FROM @TB)
DELETE FROM CTE WHERE ID>1
SELECT NAME FROM @TB;
--**Delete by Row Number** 
;WITH CTE AS(SELECT NAME,ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY NAME) ID FROM @TB)
DELETE FROM CTE WHERE ID>1;
SELECT NAME FROM @TB;

การลบข้อมูลซ้ำออกจากตารางขนาดใหญ่ (หลายล้านระเบียน) อาจใช้เวลานาน ฉันขอแนะนำให้คุณแทรกจำนวนมากในตารางชั่วคราวของแถวที่เลือกแทนที่จะเป็นการลบ '- เขียนรหัสของคุณ (จดบันทึกบรรทัดที่ 3) ด้วย CTE AS (เลือกชื่อ ROW_NUMBER () ขึ้นไป (แบ่งพาร์ติชันตามชื่อตามชื่อ) ID จาก @TB) เลือก * ลงใน #unique_records จากที่ซึ่ง ID = 1; '
Emmanuel Bull

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.