2015-04-04 70 views
0

我有一个非常大的表(数百万条记录)。有些记录有重复(基于FieldA),唯一的区别是FiedldB中的值。我想创建一个查询,它将删除基于FieldA的所有重复记录,并保留FieldB中值最低的记录。这可能吗?根据字段中的值删除重复的行

+0

是的,这是可能的。 – wildplasser 2015-04-04 13:29:00

回答

0

似乎相当简单的提取这些值:

select distinct a, 
     min(b) b 
from t 
group by a; 

小提琴例如:http://sqlfiddle.com/#!9/bc4c9/3

您应该能够从这种适应去除方法。

+0

我跑这个使用极限100,它运行良好。当我跑W/O时,它最大限度地提高了tmp文件。有没有办法像这样运行一个查询来刷新tmp,还是我要手动批量运行,例如ID> 0和ID <100?这将有点吸吮,因为有大约一百万条记录左右。 – user3649739 2015-04-05 13:34:29

+0

你为什么要写一个临时文件?我以为你想删除记录。 – 2015-04-05 13:38:30

0
CREATE TABLE TABLE1 
    (
    FieldA VARCHAR2(30), 
    FieldB VARCHAR2(30), 
    FieldC VARCHAR2(30) 
); 

INSERT INTO TABLE1 VALUES 
    ('DUMMYDATA-A1','DUMMYDATA-B1','DUMMYDATA-C1' 
); 
INSERT INTO TABLE1 VALUES 
    ('DUMMYDATA-A1','DUMMYDATA-B4','DUMMYDATA-C1' 
); 
INSERT INTO TABLE1 VALUES 
    ('DUMMYDATA-A1','DUMMYDATA-B3','DUMMYDATA-C1' 
); 
INSERT INTO TABLE1 VALUES 
    ('DUMMYDATA-A1','DUMMYDATA-B2','DUMMYDATA-C1' 
); 
COMMIT; 

SELECT FieldA, 
    FieldB, 
    FieldC, 
    RANK() OVER(PARTITION BY FieldA ORDER BY FieldB ASC) AS COLUMN_ALIAS 
FROM TABLE1; --IDENTIFIES DUPLICATES BASED ON RANK VALUE 

---PERFORM DELETE 
DELETE 
FROM TABLE1 
WHERE ROWID IN 
    (SELECT ROWID 
    FROM 
    (SELECT ROWID, 
     RANK() OVER(PARTITION BY FieldA ORDER BY FieldB ASC) AS COLUMN_ALIAS 
    FROM TABLE1 
    ) 
    WHERE COLUMN_ALIAS>1 
); 

COMMIT; 

SELECT * FROM TABLE1; -- CONTAINS A SINGLE RECORD 

RANK函数可以识别重复的记录,并且便于删除重复的记录,保留原始行。这已经在这里讨论:Deleting duplicates rows from oracle。希望这可以帮助

但是,由于DELETE本身速度较慢,因此可以在INSERT中执行适当的约束(包含数百万条记录)以避免重复输入。