2011-10-06 94 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;

请注意,插入语句可能会执行没有主键。

谢谢。