查找具有不匹配的值而没有大的自连接的行集?

问题描述:

我有这样一个表(基本的例子,不是真实的东西):查找具有不匹配的值而没有大的自连接的行集?

FKEY | NAME | ATTRIBUTE_X 
-------------------------- 
1  '...' 42 
1  '...' 42 
1  '...' 42 
2  '...' 7 
2  '...' 7 
5  '...' 42 
5  '...' 42 
5  '...' 42 
5  '...' 42 
6  '...' 300 
6  '...' 300 
.... 

凡 - 正常 - 对于每一个给定的FKEY值attribute_x的都是相同的。 (在我的真实数据中,我计算表中某些列的attribute_x,并且此属性对于所有具有相同fkey的行都必须相同。

现在我有一些行,此属性不适用。搜索整个表找到所有FKEYs不匹配attribute_x值

例:

-------------------------- 
145678973  '...' 23 
145678973  '...' 22 // Error, should also be 23 
145678973  '...' 23 

我幼稚的做法是:

SELECT distinct(TX1.FKEY) 
FROM TABLEX TX1, TABLEX TX2 
WHERE TX1.FKEY=TX2.FKEY 
    AND TX1.ATTRIBUTE_X <> TX2.ATTRIBUTE_X 
; 

但随着我的真实数据没有完成(我运行了临时表空间,在DBA将临时表空间增加到20 GIG后,查询运行了几个小时,然后保留)。

通常,是否有更高效查询这个?


我有PL/SQL一个解决方案,我只是在由FKEY排序的表圈,如果我找到一个不同的attribute_x对其中FKEY保持不变,最后取出的记录,我发现了一个错误的fkey。

但是,这似乎哦,如此原始:-)有没有一个有效的纯粹的SQL解决方案?

最简单的方法:

select fkey 
from tablex 
group by fkey 
having count(distinct attribute_x) > 1 
+0

我接受此答案而不是[Helena's](http://*.com/q/8260067/321013),因为此版本也适用于非数字'attribute_x'。 –

+0

注意:这个版本和MAX MIN版本的实际数据的自动跟踪成本完全相同:'17518' :-) –

试试这个

SELECT * FROM tablex 
WHERE (fkey, name, attribute_x) NOT IN 
    (SELECT fkey, name, attribute_x FROM tablex 
    GROUP BY fkey) 

或者(如果名字不被帐户采取)

SELECT * FROM tablex 
WHERE (fkey, attribute_x) NOT IN 
    (SELECT fkey, attribute_x FROM tablex 
    GROUP BY fkey) 
+0

这会不会返回整个表?加上它不会被认为是一个自我加入(虽然半自我加入:)? –

+0

@VincentMalgrat:不,我的查询(我测试过)只返回每个fkey具有不同属性的记录。 – Marco

+1

@MarkBannister:不,我的查询(我测试了它)返回记录,其中每个fkey都有与第一个不同的attribute_x列:) – Marco

这应该这样做

select 
    FKEY 
from 
    (
    select distinct 
    FKEY, 
    ATTRIBUTE_X 
    from 
    MYTABLE 
) 
group by 
    FKEY 
having 
    count(*) > 1 
+0

谢谢,更正。 @Mark Ba​​nnister的解决方案虽然更好。使用计数不同很容易。 – njr101

尝试用这种

select count(*),FKEY from (Select distinct FKEY,ATTRIBUTE_X from TABLEX) 
having count(*)>1 

编辑我纠正了查询有2,而不是1点

而且下面应该工作:

SELECT fkey FROM mytable GROUP BY fkey HAVING MIN(attribute_x) <> MAX(attribute_x)

+0

+1 – njr101