source

T-SQL: 중복된 행은 모두 삭제하지만 행은 유지

lovecheck 2023. 4. 7. 21:33
반응형

T-SQL: 중복된 행은 모두 삭제하지만 행은 유지

테이블이 굉장히 많아요.중복은 허용되지 않지만 행 작성 방법에 문제가 있기 때문에 이 테이블에 중복이 있는 것으로 알고 있습니다.키 열의 관점에서 여분의 행을 제거해야 합니다.다른 열의 데이터는 약간 다를 수 있지만 저는 상관하지 않습니다.하지만 이 행들 중 하나를 유지해야 합니다.SELECT DISTINT는 모든 열에 대해 작동하며 키 열에 따라 중복을 억제해야 하므로 작동하지 않습니다.

추가 행을 삭제하면서도 효율적으로 유지할 수 있는 방법은 무엇입니까?

사용 중인 버전은 밝히지 않았지만 SQL 2005 이상에서는 OVER 절과 함께 공통 테이블 식을 사용할 수 있습니다.이런 식으로 진행됩니다.

WITH cte AS (
  SELECT[foo], [bar], 
     row_number() OVER(PARTITION BY foo, bar ORDER BY baz) AS [rn]
  FROM TABLE
)
DELETE cte WHERE [rn] > 1

가지고 놀면서 뭐가 나오는지 보세요.

(편집: 도움이 되기 위해 누군가가 편집했습니다.ORDER BY절을 참조해 주세요.여기서 원하는 대로 주문할 수 있습니다.CTE가 반환하는 열 중 하나일 필요는 없습니다.실제로 여기서 흔히 볼 수 있는 사용 사례는 "foo, bar"가 그룹 식별자이고 "baz"가 일종의 타임스탬프라는 것입니다.최신 정보를 유지하기 위해ORDER BY baz desc)

쿼리 예시:

DELETE FROM Table
WHERE ID NOT IN
(
SELECT MIN(ID)
FROM Table
GROUP BY Field1, Field2, Field3, ...
)

여기서fields중복 행을 그룹화하는 열입니다.

여기 저의 반전이 있습니다. 실행 가능한 예를 들어 보겠습니다.이것은, 다음과 같은 상황에서만 유효합니다.Id고유하며 다른 열에 중복된 값이 있습니다.

DECLARE @SampleData AS TABLE (Id int, Duplicate varchar(20))

INSERT INTO @SampleData
SELECT 1, 'ABC' UNION ALL
SELECT 2, 'ABC' UNION ALL
SELECT 3, 'LMN' UNION ALL
SELECT 4, 'XYZ' UNION ALL
SELECT 5, 'XYZ'

DELETE FROM @SampleData WHERE Id IN (
    SELECT Id FROM (
        SELECT 
            Id
            ,ROW_NUMBER() OVER (PARTITION BY [Duplicate] ORDER BY Id) AS [ItemNumber]
            -- Change the partition columns to include the ones that make the row distinct
        FROM 
            @SampleData
    ) a WHERE ItemNumber > 1 -- Keep only the first unique item
)

SELECT * FROM @SampleData

그 결과:

Id          Duplicate
----------- ---------
1           ABC
3           LMN
4           XYZ

왜 내가 처음에 그렇게 생각했는지...가장 간단한 방법은 아니지만 효과가 있습니다.

언급URL : https://stackoverflow.com/questions/6025367/t-sql-deleting-all-duplicate-rows-but-keeping-one

반응형