PostgreSQL 8.3.8 데이터베이스에 키 / 제약 조건이없고 정확히 동일한 값을 가진 여러 행이있는 테이블이 있습니다.
모든 중복을 제거하고 각 행의 사본을 1 개만 유지하고 싶습니다.
특히 중복을 식별하는 데 사용할 수있는 하나의 열 ( “키”라고 함)이 있습니다 (즉, 각 고유 “키”에 대해 하나의 항목 만 있어야 함).
어떻게 할 수 있습니까? (이상적으로는 단일 SQL 명령 사용)이 경우 속도는 문제가되지 않습니다 (행이 몇 개만 있음).
답변
DELETE FROM dupes a
WHERE a.ctid <> (SELECT min(b.ctid)
FROM dupes b
WHERE a.key = b.key);
답변
더 빠른 솔루션은
DELETE FROM dups a USING (
SELECT MIN(ctid) as ctid, key
FROM dups
GROUP BY key HAVING COUNT(*) > 1
) b
WHERE a.key = b.key
AND a.ctid <> b.ctid
답변
이것은 빠르고 간결합니다.
DELETE FROM dupes T1
USING dupes T2
WHERE T1.ctid < T2.ctid -- delete the older versions
AND T1.key = T2.key; -- add more columns if needed
자세한 정보를 포함하는 고유 식별자없이 중복 행을 삭제하는 방법의 내 대답을 참조하십시오.
답변
나는 이것을 시도했다 :
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);
Postgres 위키에서 제공 :
답변
나만의 버전을 만들어야했습니다. @a_horse_with_no_name에 의해 작성된 버전은 내 테이블에서 너무 느립니다 (21M 행). 그리고 @rapimo는 단순히 dups를 삭제하지 않습니다.
PostgreSQL 9.5에서 사용하는 것은 다음과 같습니다.
DELETE FROM your_table
WHERE ctid IN (
SELECT unnest(array_remove(all_ctids, actid))
FROM (
SELECT
min(b.ctid) AS actid,
array_agg(ctid) AS all_ctids
FROM your_table b
GROUP BY key1, key2, key3, key4
HAVING count(*) > 1) c);
답변
임시 테이블을 사용합니다.
create table tab_temp as
select distinct f1, f2, f3, fn
from tab;
그런 다음, 삭제 tab
및 이름 변경 tab_temp
에 tab
.
답변
id
열별로 모든 고유 ID를 찾고 고유 목록에없는 다른 ID를 제거하는 또 다른 방법 ( 테이블에 있는 고유 필드가있는 경우에만 작동 )
DELETE
FROM users
WHERE users.id NOT IN (SELECT DISTINCT ON (username, email) id FROM users);
