2011-10-06 141 views
3

我有一個表,該表如下刪除從表中重複:如何使用SQL查詢

emp_name emp_address sex matial_status 
uuuu  eee   m s 
iiii  iii   f s 
uuuu  eee   m s 

我想刪除基於3個字段重複的條目emp_name長度,emp_address和性別。 和我得到的表(刪除重複項後),應該像 -

emp_name emp_address sex marital_status 
uuuu  eee   m  s 
iiii  iii   f  s 

我不能夠回憶起如何寫一個SQL查詢這一點。有人請求幫助?

+3

如果您不打算在該行的所有列上進行復制,那麼當找到重複項時,您將如何決定保留哪一行? –

回答

1

它看起來像所有四個列的值複製,所以你可以做到這一點 -

select distinct emp_name, emp_address, sex, marital_status 
from YourTable 

但是,如果婚姻狀況是不同的,你有一些列在此基礎上進行選擇(對於例如,你想要最新基於列CREATE_DATE記錄),你可以做到這一點

select emp_name, emp_address, sex, marital_status 
from YourTable a 
where not exists (select 1 
        from YourTable b 
        where b.emp_name = a.emp_name and 
         b.emp_address = a.emp_address and 
         b.sex = a.sex and 
         b.create_date >= a.create_date) 
2

單程

select emp_name, emp_address, sex, max(marital_status) as marital_status 
from Yourtable 
group by emp_name, emp_address, sex 

由於我不知道你想要什麼,我用最大的婚姻狀況

又見Including an Aggregated Column's Related Values更多的例子

+0

+1似乎是正確的。 (演示:http://sqlize.com/Vn04R6Gjo9) – mellamokb

+0

爲什麼你使用了max函數? – user7

+0

查看@ Ralph對你的問題的評論。你有什麼邏輯來確定要保留哪個重複的婚姻狀態? – mellamokb

5

我會創建一個新表在您想保持唯一性的列上使用唯一索引。然後從舊錶中插入新的,忽略重複行的警告。最後,我將刪除(或重命名)舊錶並將其替換爲新表。在MySQL中,這看起來像

CREATE TABLE tmp LIKE mytable; 
ALTER TABLE tmp ADD UNIQUE INDEX myindex (emp_name, emp_address, sex, marital_status); 
INSERT IGNORE INTO tmp SELECT * FROM mytable; 
DROP TABLE mytable; 
RENAME TABLE tmp TO mytable; 

或類似的東西(這是完全未經測試)。

0

如果你是好與性能和簡單的交易空間,然後在emp_name | emp_address | sex組合的副本可能被淘汰,通過引入計算/派生列在查詢時使用CHECKSUM() TSQL方法和DISTINCT關鍵字。

下面有CHECKSUM的示例:

SELECT CHECKSUM(*) FROM HumanResources.Employee WHERE EmployeeID = 2 

谷歌周圍並創建包含3列的校驗依賴列。 然後您可以通過查找來選擇不同的行at this question

+0

我也邀請了一些關於這個答案的評論 - 我需要知道這是否足夠好(即使對於800k行的表格) – Zasz

4

這不是查詢,而是刪除語句。它會刪除/從你的桌子

;with C as 
(
    select row_number() over(partition by DUPLICATE_VAARS_DECISION 
          order by NODE_EQ_NO) as rn 
    from yourtable 
) 
delete C 
where rn > 1 

刪除重複的行如果你只在查詢的表興趣,並得到非重複,你應該使用這樣的結果。

;with C as 
(
    select *, 
     row_number() over(partition by DUPLICATE_VAARS_DECISION 
          order by NODE_EQ_NO) as rn 
    from yourtable 
) 
select * 
from C 
where rn = 1 
+1

感謝這個工程!對於第一條語句,刪除重複的,這是更容易理解這樣的:;具有(由描述 爲了通過描述),如從[YourTable] RN 選擇ROW_NUMBER()以上(分區)C作爲 刪除C 其中RN > 1 –

0

最好的答案就在這裏:
使用該SQL語句來識別額外複製行:

 select * from Employee a 
where %%physloc%% >
(select min(%%physloc%%) from Employee b
where a.emp_name=b.emp_name and a.emp_address=b.emp_address and a.sex=b.sex);

你將得到額外的行:

uuuu eee m s


使用此SQL語句刪除多餘的重複行:

 delete from Employee a 
where %%physloc%% >
(select min(%%physloc%%) from Employee b
where a.emp_name=b.emp_name and a.emp_address=b.emp_address and a.sex=b.sex);


對於所有重複的記錄,只有一個與最低的物理位置被保留。該方法可以應用於刪除各種重複的行。

我假設您使用MS SQL Server。如果您使用的是Oracle數據庫,那麼你可以只更換 '%% physloc %%' 與 '的rowid'

享受代碼!

0

我知道這是舊的文章,但最近我測試的解決方案,並希望分享,如果任何人能發現我的解決方案有幫助 -

CREATE TABLE tmpTable LIKE yourTable; 插入tmpTablecol1col2 ... colN)SELECT DISTINCT col1col2 ... colN FROM yourTable WHERE 1; drop table yourTable; RENAME TABLE tmpTable TO yourTable;

請注意,插入語句可能會執行沒有主鍵。

謝謝。