0

假设我的 Oracle DB 中有下表:

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

而且,我想要得到的是一个不同的记录列表,其中 forCol1Col2不同的 - 忽略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并且可能认为这可以使用自连接来完成......这更像是一个问题 /学习在更好(也许更有效)的查询中获得结果的新方法。

谢谢!!!

4

2 回答 2

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 )

很可能会加快所有这些查询。

于 2013-10-17T21:39:30.780 回答
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;

having但是,这不是有效的 SQL,因为子句中不允许使用分析函数。

于 2013-10-17T22:59:16.850 回答