回答:
基本的な考え方は、カウント集計でネストされたクエリを使用することです。
select * from yourTable ou
where (select count(*) from yourTable inr
where inr.sid = ou.sid) > 1
内部クエリのwhere句を調整して、検索を絞り込むことができます。
コメントで言及されているものに対して別の良い解決策があります(しかし、誰もがそれらを読むわけではありません):
select Column1, Column2, count(*)
from yourTable
group by Column1, Column2
HAVING count(*) > 1
またはより短い:
SELECT (yourTable.*)::text, count(*)
FROM yourTable
GROUP BY yourTable.*
HAVING count(*) > 1
select co1, col2, count(*) from tbl group by col1, col2 HAVING count(*)>1
「PostgreSQLで重複行を検索する」から、スマートなソリューションを以下に示します。
select * from (
SELECT id,
ROW_NUMBER() OVER(PARTITION BY column1, column2 ORDER BY id asc) AS Row
FROM tbl
) dups
where
dups.Row > 1
SELECT * FROM ( SELECT *, LEAD(row,1) OVER () AS nextrow FROM ( SELECT *, ROW_NUMBER() OVER(w) AS row FROM tbl WINDOW w AS (PARTITION BY col1, col2 ORDER BY col3) ) x ) y WHERE row > 1 OR nextrow > 1;
ROW_NUMBER()
、後にCOUNT(*)
追加rows between unbounded preceding and unbounded following
ORDER BY id asc
DELETE ...USING
いくつかのマイナーな調整を伴うデュープの削除にも同様に機能します
重複するフィールドで同じテーブルに結合してから、idフィールドで逆結合することができます。最初のテーブルエイリアス(tn1)からidフィールドを選択し、次に2番目のテーブルエイリアスのidフィールドでarray_agg関数を使用します。最後に、array_agg関数が正しく機能するように、結果をtn1.idフィールドでグループ化します。これにより、レコードのIDと、結合条件に適合するすべてのIDの配列を含む結果セットが生成されます。
select tn1.id,
array_agg(tn2.id) as duplicate_entries,
from table_name tn1 join table_name tn2 on
tn1.year = tn2.year
and tn1.sid = tn2.sid
and tn1.user_id = tn2.user_id
and tn1.cid = tn2.cid
and tn1.id <> tn2.id
group by tn1.id;
明らかに、1つのidのduplicate_entries配列にあるidは、結果セットに独自のエントリも持っています。この結果セットを使用して、「真実」のソースになるIDを決定する必要があります。削除してはならない1つのレコード。多分あなたはこのようなことをすることができます:
with dupe_set as (
select tn1.id,
array_agg(tn2.id) as duplicate_entries,
from table_name tn1 join table_name tn2 on
tn1.year = tn2.year
and tn1.sid = tn2.sid
and tn1.user_id = tn2.user_id
and tn1.cid = tn2.cid
and tn1.id <> tn2.id
group by tn1.id
order by tn1.id asc)
select ds.id from dupe_set ds where not exists
(select de from unnest(ds.duplicate_entries) as de where de < ds.id)
重複している最小のIDを選択します(IDがint PKを増加させていると想定)。これらは、保持するIDです。
簡単にするために、列の年にのみ一意制約を適用し、主キーはidという名前の列であると仮定します。
実行する必要がある重複値を見つけるために、
SELECT year, COUNT(id)
FROM YOUR_TABLE
GROUP BY year
HAVING COUNT(id) > 1
ORDER BY COUNT(id);
上記のsqlステートメントを使用すると、テーブル内の重複するすべての年を含むテーブルが得られます。ためには、最新の重複エントリの以外のすべての重複を削除するには、あなたは、上記のSQL文を使用する必要があります。
DELETE
FROM YOUR_TABLE A USING YOUR_TABLE_AGAIN B
WHERE A.year=B.year AND A.id<B.id;