2

假设我的 Oracle DB 中有一个如下所示的表:

COL_A     COL_B     COL_C     COL_D   .... COL_XXX
A         1         2         1    ....
A         1         2         2    ....
A         1         2         3    ....
A         2         3         4    ....
B         1         2         5    ....
B         1         2         6    ....
B         1         2         7    ....
B         4         2         8    ....
B         1         4         9    ....
C         1         2         10    ....
C         1         2         11    ....
C         1         2         12    ....
C         1         2         13    ....
C         1         2         14    ....

而且我只想找到COL_A相同和COL_B不同的记录,COL_C而不管表中的所有其他列(因此不能只Distinct在我的 SQL 中使用子句)并忽略所有值都是的任何记录的所有值都相同COL_A(在此示例中,当= "C"时, COL_B&的所有值都相同)。COL_CCOL_A

(换句话说 - 仅返回匹配的COL_B/COL_C值至少存在一个差异的值,COL_A而不管表的其他行如何。)

所以,我希望我的结果集是:

COL_A     COL_B     COL_C
A         1         2    
A         2         3    
B         1         2    
B         4         2    
B         1         4    

因此,我编写的 SQL 如下所示:

Select b.* FROM
(
   Select a.*, COUNT(a.COL_A) OVER(PARTITION BY a.COL_A) as CNT FROM
   (
       select DISTINCT COL_A, COL_B, COL_C from MyTable) a
   ) b
WHERE
b.CNT > 1

现在,这可行,但我想知道是否有更好/更有效的方法来获取这些数据?

谢谢!!!

4

2 回答 2

3

将表连接到自身以查找与 COL_A 匹配但具有不同 COL_B 或 COL_C 的其他行:

select distinct t1.COL_A, t1.COL_B, t1.COL_C
from MyTable t1
join MyTable t2 on t1.COL_A = t2.COL_A
    AND (t1.COL_B != t2.COL_B OR t1.COL_C != t2.COL_C)

看到这个在 SQLFiddle 上工作

如果要对行进行排序,请order by在末尾添加一个。

有了这方面的索引,(COL_A)效果会非常好。使用复合索引(COL_A, COL_B, COL_C)会表现得非常好。

于 2013-08-26T14:37:15.407 回答
1

您可以使用exists子查询来要求至少有一行具有相同col_a但不同的col_bcol_c存在:

select  distinct col_a, col_b, col_c
from    YourTable yt1
where   exists
        (
        select  *
        from    YourTable yt2
        where   yt1.col_a = yt2.col_a
                and (yt1.col_b <> yt2.col_b
                     or yt1.col_c <> yt2.col_c)
        )

在 SQL Fiddle 上查看它。

于 2013-08-26T14:38:57.663 回答