我有一個PostgreSQL數據庫的表稱爲「user_links」目前允許下列重複字段:如何找到重複記錄的PostgreSQL
year, user_id, sid, cid
唯一性約束是目前所謂的「ID」的第一場,但是我我現在想要添加一個約束,以確保year
,user_id
, sid
和cid
都是唯一的,但我無法應用該約束,因爲重複值已存在,違反了此約束。
有沒有辦法找到所有的重複?
我有一個PostgreSQL數據庫的表稱爲「user_links」目前允許下列重複字段:如何找到重複記錄的PostgreSQL
year, user_id, sid, cid
唯一性約束是目前所謂的「ID」的第一場,但是我我現在想要添加一個約束,以確保year
,user_id
, sid
和cid
都是唯一的,但我無法應用該約束,因爲重複值已存在,違反了此約束。
有沒有辦法找到所有的重複?
的基本思想將使用嵌套查詢與數聚集:
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
你也可以使用HAVING:'select col1,col2,count(*)from tbl group by col1,col2 HAVING count(*)> 1' – alexkovelsky 2015-08-28 07:27:58
感謝@alexkovelsky有聲明對我來說更容易修改並且運行更快。我會建議一個答案,以獲得更高的知名度。 – Vesanto 2016-03-14 15:58:25
這些選項對我有用,其他人對結果進行分組,而這些選項給了我所有重複記錄,而不僅僅是重複記錄,謝謝! – rome3ro 2017-07-12 18:13:39
你可以加入到同一個表中的字段將被複制,然後反向加入id字段。從第一個表別名(tn1)中選擇id字段,然後在第二個表別名的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;
很明顯,id位於duplicate_entries數組中的一個id,在結果集中也會有自己的條目。你將不得不使用這個結果集來決定你想要成爲「真相」源的哪個ID。一個不應該被刪除的記錄。也許你可以做這樣的事情:
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。
嘗試添加你的代碼的解釋。 – ianaya89 2015-01-26 20:20:56
@ ianaya89添加了解釋。 – pwnyexpress 2015-01-26 21:03:22
從 「Find duplicate rows with PostgreSQL」 這裏是聰明的解決辦法:在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
這是快!在幾秒鐘內完成數百萬行的工作。其他答案只是掛在那裏... – dmvianna 2016-03-04 06:50:26
就像我看到的,這個查詢不考慮組內的所有行。它只顯示重複的東西,部分副本將與rownum = 1。糾正我如果我錯了 – 2016-05-24 08:33:43
@vladimir Filipchenko要與所有行,添加一個級別Alexkovelsky解決方案: 'SELECT * FROM( SELECT * ,鉛(行,1)OVER()AS nextrow FROM( SELECT *, ROW_NUMBER()OVER(w)的AS 行FROM TBL 窗口W AS(PARTITION BY COL1,COL2 ORDER BY COL3) )× ) y WHERE row> 1 OR nextrow> 1;' – 2016-07-28 17:34:16
可能重複(http://stackoverflow.com/questions/14471179/find-duplicate-rows-with-postgresql ) – drs 2015-05-26 19:30:09