我正在使用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加入表,这可能会让任何读取代码的人感到困惑! 我相信这可以用分析函数,但我不知道怎么做?
答案 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中。