2013-10-17 36 views
0

假设我在Oracle数据库如下表:甲骨文 - 查找匹配的记录用不同的值一个字段

Col1:  Col2: ... Coln: 
1   a  ... 1 
1   a  ... 1 
1   b  ... 1 
1   b  ... 1 
1   c  ... 1 
1   a  ... 1 
2   d  ... 1 
2   d  ... 1 
2   d  ... 1 
3   e  ... 1 
3   f  ... 1 
3   e  ... 1 
3   e  ... 1 
4   g  ... 1 
4   g  ... 1 

而且,我想是的记录,其中,为Col1鲜明的列表,Col2是不同的 - 忽略Col2匹配所有Col1的任何时间。

因此,在这个例子中,我想获得的结果集:

Col1:  Col2: 
1   a  
1   b  
1   c  
3   e  
3   f 

现在,我想通了,如何使用,感觉手头的问题相当复杂的查询做到这一点:

With MyData as 
(
    SELECT b.Col1, b.Col2, count(b.Col2) over(Partition By b.Col1) as cnt from 
    (
    Select distinct a.Col1, a.Col2 from MyTable a 
    ) b 
) 

select Col1, Col2 
from MyData 
where cnt > 1 
order by Col1 

什么我不知道是什么,是一个更好的办法做到这一点 - 我没能做到这一点使用GROUP BY & HAVING,可能认为这也许可以使用自加入...这是更要做一个观察/学习新方法获得重新认识的人导致更好的(也许更有效)查询。

谢谢!

回答

3

尝试此查询:

SELECT distinct * 
FROM table1 t1 
WHERE EXISTS 
(SELECT 1 FROM table1 t2 
    WHERE t1.col2 <> t2.col2 
    AND t1.col1 = t2.col1 
) 
order by 1,2 

演示:http://www.sqlfiddle.com/#!4/9ce10/12

-----编辑-------

是的,还有其他的方法来做到这一点:

SELECT distinct col1, col2 
FROM table1 t1 
WHERE col2 <> ANY (
    SELECT col2 FROM table1 t2 
    WHERE t1.col1 = t2.col1 
) 
order by 1,2; 

SELECT distinct col1, col2 
FROM table1 t1 
WHERE NOT col2 = ALL (
    SELECT col2 FROM table1 t2 
    WHERE t1.col1 = t2.col1 
) 
order by 1,2 
; 

SELECT distinct t1.col1, t1.col2 
FROM table1 t1 
JOIN table1 t2 
ON t1.col1 = t2.col1 AND t1.col2 <> t2.col2 
order by 1, 2 
; 


SELECT t1.col1, t1.col2 
FROM table1 t1 
JOIN table1 t2 
ON t1.col1 = t2.col1 
GROUP BY t1.col1, t1.col2 
HAVING COUNT(distinct t2.col2) > 1 
order by 1, 2 
; 


SELECT t1.col1, t1.col2 
FROM 
table1 t1 
JOIN (
    SELECT col1 
    FROM table1 
    GROUP BY col1 
    HAVING COUNT(distinct col2) > 1 
) t2 
ON t1.col1 = t2.col1 
GROUP BY t1.col1, t1.col2 
ORDER BY t1.col1, t1.col2 
; 

演示 - >http://www.sqlfiddle.com/#!4/9ce10/33

尝试一切,我真的不知道他们将如何执行您的数据。
但是,创建一个综合指数:

CREATE INDEX name ON table1(col1, col2) 

将最有可能加速这些查询。

+0

这是行得通! - 谢谢!!!仅仅为了我的教育,这会比我写查询的方式更有效率吗?另外,由于这只是为了我学习,你能想出其他方法来做到这一点吗? - 我只是好奇,看看有什么可用来增加我的SQL实力:) –

+0

和!!!再次感谢! –

+1

我很高兴我能帮上忙。我附加了一些热门的例子,以其他方式做到这一点 - 仅用于学习目的。 – krokodilko

1

下面是一个使用聚合和分析功能的方法:

with t as (
     select col1, col2, 
      count(*) over (partition by col1) as cnt 
     from table1 
     group by col1, col2 
    ) 
select col1, col2 
from t 
where cnt > 1; 

我想要做的是:

select col1, col2, 
     count(*) over (partition by col1) as cnt 
    from table1 
    group by col1, col2 
    having count(*) over (partition by col1) > 1; 

然而,这不是有效的SQL,因为分析功能having条款中不允许。

+0

感谢您的支持,但不幸的是,'count'也会计算具有相同值的重复记录,所以它会计算出“Col2”的非重复值:( –

+0

您有其他想法吗? ?不幸的是,我会提前告诉你,我将把Kordirko标记为正确的答案,因为他是第一个解决这个问题的解决方案,但是如果你愿意帮助我指导正确的学习目的,我将不胜感激!!!!! –