我必須從沒有主鍵或唯一約束的表中清除記錄。從沒有唯一列的表中刪除部分重複項
表定義:
create table person(
name text,
staff_id integer,
work_code text,
location
);
不出所料,它含有大量的重複和部分重複的。 將記錄轉換爲唯一集合的最佳方式是什麼?我不必關心除名稱和職員以外的其他專欄
我必須從沒有主鍵或唯一約束的表中清除記錄。從沒有唯一列的表中刪除部分重複項
表定義:
create table person(
name text,
staff_id integer,
work_code text,
location
);
不出所料,它含有大量的重複和部分重複的。 將記錄轉換爲唯一集合的最佳方式是什麼?我不必關心除名稱和職員以外的其他專欄
正如你
不必在意除了名字等欄目和staff_id
這可能是你的程序來清理表:
1 )創建一個臨時表獨特行:
CREATE TEMP TABLE p_tmp AS
SELECT DISTINCT ON (name, staff_id)
name, staff_id, work_code, location
FROM person
ORDER BY name, staff_id, work_code, location;
我隨意選擇「第一行每(name, staff_id)
- 最小work_code
和匹配location
。
2)空表:
TRUNCATE person;
3)重新插入獨特的元組:
INSERT INTO person SELECT * FROM p_tmp;
確保,受騙者不悄悄潛回裏添加一個代理主鍵:
ALTER TABLE person ADD COLUMN person_id serial PRIMARY KEY;
ALTER TABLE person ADD UNIQUE (name, staff_id);
或者只需添加一個多列主鍵:
ALTER TABLE person ADD PRIMARY KEY (name, staff_id);
臨時表將在會話結束時自動丟棄。
當然,所有這一切最好在一個transaction內完成,所以在不太可能出現半途遇到問題的情況下不會丟失任何東西。有些客戶端會自動執行一次執行的一批SQL語句。
當然'max'比'min'更好;使空值最不可能被選中。 – Ben 2012-01-01 20:55:04
@Ben:max()和min()都不會在**任何**值上選擇NULL。 – 2012-01-01 21:05:20
@ErwinBrandstetter謝謝你,它很好地工作 – 2012-01-02 04:47:19
也許這樣?
select t.name, t.staff_id, t.work_code, t.location
from (
select name, staff_id, work_code, location, count(*) nr
from person
group by name, staff_id, work_code, location
) t
where t.nr > 1;
我很抱歉,我的意思是我需要擺脫部分重複行,但保留與所有其他值的1唯一行以及。我嘗試不同,但它仍然返回所有行 – 2012-01-01 19:27:27
請參閱後編輯,做它回答您的需求? – fge 2012-01-01 19:33:45
它抱怨說我需要將所有t。*列包含在group by子句中。當我這樣做時,它不返回任何行。我測試了子查詢,並且「nr」列從不包含大於1的值。 – 2012-01-01 19:53:10
你稱之爲「部分重複」? – fge 2012-01-01 19:17:29
@ work_code和location_fge變體,我只需要保留name和staff_id – 2012-01-01 19:18:47
你真的關心哪些值會得到最終結果嗎? – fge 2012-01-01 19:19:34