使用分析函数查询具有其他列的列的非重复值

时间:2013-04-05 11:33:12

标签: sql oracle

我正在使用Oracle 11g第1版。 关注this questions

拥有这组行:

Name     Contact_No

A        123
A        124
B        125
C        126
C        127

我想使用分析函数返回:

Name     Contact_No
B        125

我能做到这一点

select name, Contact_No
from   tbl_name
where  name in ( SELECT name
                 FROM   tbl_name
                 GROUP  BY name
                 HAVING COUNT(name) = 1
                )

或者

SELECT name, max(Contact_No)
FROM   tbl_name
GROUP  BY name
HAVING COUNT(name) = 1

但是我想要一个解决方案,我可以避免使用子查询或者使用min / max加入表,这可能会让任何读取代码的人感到困惑! 我相信这可以用分析函数,但我不知道怎么做?

1 个答案:

答案 0 :(得分:2)

你是对的,你需要使用分析功能;如果你想返回整行。根据您当前的查询判断为分析COUNT()

select *
  from ( select a.*, count(*) over ( partition by name ) as ct
           from tbl_name )
 where ct = 1

为了解释,除非没有做,否则分区有效地与GROUP BY相同。这会计算名称的记录数,并在线返回,无论具有该名称的记录数。然后,您可以限制此生成的列。

虽然这确实使用了子查询,但这种方法没有任何本质上的错误。您只扫描一次表/索引;与您当前扫描两次的示例不同。

我通常建议您在NAME处有一个索引,但这取决于您的具体情况。您可能需要扫描整个表格,在这种情况下索引不会帮助您。

此外,如果具有这两列,则分析查询中没有任何意义。您可以使用第二个选项获得相同的结果。

SELECT name, max(Contact_No)
  FROM tbl_name
 GROUP BY name
HAVING COUNT(name) = 1

当您需要返回其他列时,分析查询非常有用,您不能将这些列包含在GROUP BY中。