我有一個包含這些列的表:
ID (varchar)
SETUP_ID (varchar)
MENU (varchar)
LABEL (varchar)
我想要實作的是基于兩列從表中洗掉所有重復項(SETUP_ID, MENU)。
表我有:
id | setup_id | menu | label |
-------------------------------------
1 | 10 | main | txt |
2 | 10 | main | txt |
3 | 11 | second | txt |
4 | 11 | second | txt |
5 | 12 | third | txt |
我想要的表:
id | setup_id | menu | label |
-------------------------------------
1 | 10 | main | txt |
3 | 11 | second | txt |
5 | 12 | third | txt |
uj5u.com熱心網友回復:
您可以嘗試按照這些方法洗掉除第一行之外的所有內容,以防出現重復(請注意,這未以任何方式進行測驗!):
DELETE FROM your_table WHERE id IN (
SELECT unnest(duplicate_ids[2:]) FROM (
SELECT array_agg(id) AS duplicate_ids FROM your_table
GROUP BY SETUP_ID, MENU
HAVING COUNT(*) > 1
)
)
)
上面的代碼將重復行 ( COUNT(*) > 1)的 id 收集到一個陣列 ( array_agg) 中,然后取出該陣列 ( [2:]) 中除第一個元素之外的所有元素,并將 id 值“分解”為行 ( unnest)。外部查詢只會洗掉以該結果結尾的每個 id。
uj5u.com熱心網友回復:
您可以使用group by來獲取唯一性setup_id。
SELECT * FROM TABLE_NAME GROUP BY setup_id, menu
uj5u.com熱心網友回復:
對于 mysql,這里已經回答了類似的問題Find and remove duplicate rows by two columns
嘗試任何方法是否有助于解決此問題。
我喜歡下面的一個MySql:
ALTER IGNORE TABLE your_table ADD UNIQUE (SETUP_ID, MENU);
uj5u.com熱心網友回復:
DELETE t1
FROM table_name t1
join table_name t2 on
(t2.setup_id = t1.setup_id or t2.menu = t1.menu) and t2.id < t1.id
uj5u.com熱心網友回復:
我找到了最適合我的解決方案。如果有人需要,這里是:
DELETE FROM table_name
WHERE id IN
(SELECT id
FROM
(SELECT id,
ROW_NUMBER() OVER( PARTITION BY setup_id,
menu
ORDER BY id ) AS row_num
FROM table_name ) t
WHERE t.row_num > 1 );
uj5u.com熱心網友回復:
您可以使用公用表運算式 (cte) 實作此目的
with cte as (
select id, setup_id, menu,
row_number () over (partition by setup_id, menu, label) rownum
from atable )
delete from atable a
where id in (select id from cte where rownum >= 2)
這將為您提供所需的輸出。
公共表運算式檔案
uj5u.com熱心網友回復:
有多種方法可以根據條件查找和洗掉所有重復行。但我喜歡內連接方法,即使在大量資料中也能運行得非常快。請檢查以下內容:
DELETE T1 FROM <TableName> T1
INNER JOIN <TableName> T2
WHERE
T1.id > T2.id AND
T1.<ColumnName1> = T2.<ColumnName1> AND T1.<ColumnName2> = T2.<ColumnName2>;
在你的情況下,你可以寫如下:
DELETE T1 FROM <TableName> T1
INNER JOIN <TableName> T2
WHERE
T1.id > T2.id AND
T1.setup_id = T2. setup_id;
如果您遇到任何問題或需要更多幫助,請告訴我。
uj5u.com熱心網友回復:
鏈接:https : //www.postgresql.org/docs/current/queries-union.html
https://www.postgresql.org/docs/current/sql-select.html#SQL-DISTINCT
讓我們的表名是一個
select distinct on (setup_id,menu ) a.* from a;
關鍵點:DISTINCT ON 運算式必須匹配最左邊的 ORDER BY 運算式。ORDER BY 子句通常包含附加運算式,用于確定每個 DISTINCT ON 組中行的所需優先級。
這意味著您只能通過 setup_id,menu在這個不同的查詢范圍內訂購。
想要相反:
EXCEPT回傳所有在 query1 結果中但不在 query2 結果中的行。(這有時稱為兩個查詢之間的差異。)同樣,除非使用EXCEPT ALL,否則會消除重復項。
SELECT * FROM a
EXCEPT
select distinct on (setup_id,menu ) a.* from a;
uj5u.com熱心網友回復:
假設一個名為tblwheresetup_id和menu都定義的表,NOT NULL并且id是PRIMARY KEY.
EXISTS會做得很好:
DELETE FROM tbl t0
WHERE EXISTS (
SELECT FROM tbl t1
WHERE t1.setup_id = t0.setup_id
AND t1.menu = t0.menu
AND t1.id < t0.id
);
這將洗掉id找到具有較低重復項的每一行,有效地僅保留id每組重復項中最小的行。索引(setup_id, menu)甚至(setup_id, menu, id)將大大有助于大表的性能。
如果沒有 PK 和可靠的UNIQUE(組合)列,您可以回退到使用ctid. 如果可以涉及 NULL 值,則需要指定如何處理這些值。
考慮:
- 洗掉小表中的重復行
- 如何洗掉沒有唯一識別符號的重復行
- 我如何(或可以)在多列上選擇 DISTINCT?
經過清理重復,增加一個UNIQUE約束,以防止新的受騙者:
ALTER TABLE tbl ADD CONSTRAINT tbl_setup_id_menu_uni UNIQUE (setup_id, menu);
如果您在 上有索引(setup_id, menu),請立即洗掉它。它被UNIQUE約束所取代。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/391474.html
標籤:sql PostgreSQL的 重复
上一篇:給定JSONB中的逗號分隔字串,查詢另一個表中的匹配屬性
下一篇:即使指定了架構,關系也不存在
