Oracle - 选择子集不重复的记录

时间:2014-10-13 16:04:08

标签: sql oracle

我有一个oracle数据集,其中包含以下列F1,F2,F3,F4,如下所示:

A, B, C, D
A, B, C, E
A, F, C, D
A, G, C, D

我想过滤掉F1和F2列中的重复字段。从上面的例子中,我看到第1行和第2行在字段(F1,F2)中具有相同的值(A,B),我需要得到

A, B, C, D
or
A, B, C, E

但不是两者兼而有之。所以我期望的最终结果是:

A, B, C, D
A, F, C, D
A, G, C, D

A, B, C, E
A, F, C, D
A, G, C, D

如何发布Oracle声明以实现我的目标? 我试过了:

SELECT * FROM T WHERE (ROWID,F1,F2) IN
(SELECT DISTINCT  ROWID, F1,F2 FROM T)

但声明没有帮助,仍然打印出来。 请帮忙。

以下是创建测试数据集的快速而脏的脚本:

  CREATE TABLE "T" 
   (    
    "F1" VARCHAR2(20 BYTE), 
    "F2" VARCHAR2(20 BYTE), 
    "F3" VARCHAR2(20 BYTE), 
    "F4" VARCHAR2(20 BYTE)
   ) 

Insert into T (F1,F2,F3,F4) values ('A','B','C','D');
Insert into T (F1,F2,F3,F4) values ('A','B','C','E');
Insert into T (F1,F2,F3,F4) values ('A','F','C','D');
Insert into T (F1,F2,F3,F4) values ('A','G','C','H');

2 个答案:

答案 0 :(得分:2)

是否符合您的需求:

SELECT T.*
FROM T 
JOIN (SELECT F1, F2, MIN(ROWID) RID FROM T GROUP BY(F1,F2)) O
ON T.ROWID = O.RID

请参阅http://sqlfiddle.com/#!4/dcf9c/4

内部查询将删除F1,F2上的重复内容(确定性地保留最小 ROWID以防重复)。然后外部选择是ROWID上的简单连接以提取整行。


如果T是视图,则无法使用ROWID。所以你将不得不依赖这样的东西:

SELECT F1, F2, F3, MIN(F4) F4
FROM T 
NATURAL JOIN (SELECT F1, F2, MIN(F3) F3 FROM T GROUP BY(F1,F2)) O
GROUP BY(F1,F2,F3);

请参阅http://sqlfiddle.com/#!4/dcf9c/8

这里的关键思想是创建一个具有不同F1,F2的3-uple和相应的最小F3(内部查询)。然后通过添加最小F4(外部查询)来扩展该3-uple。通过嵌套更多查询,可以很容易地将其推广到N-uple。

答案 1 :(得分:0)

使用它可以获得更好的性能(因为它可以避免连接)

SELECT DISTINCT 
F1, 
F2, 
LAST_VALUE(F3) OVER (PARTITION BY F1, F2) AS F3, 
LAST_VALUE(F4) OVER (PARTITION BY F1, F2) AS F4
FROM T