[英]Oracle - Arbitrarily pick one of multiple rows based on single unique key
早上好! 我正在寻找一种技巧来维护一个唯一的键列表,其中可能会发生一对多的关系。
问题
我正在使用一个可怕的非标准化数据库,不幸的是重新设计是不可能的。 我有一个1NF主表,其中包含许多与以下类似的传递和部分键依赖关系:
Cmpd_Key Group Subgroup Group_Desc
A1 | A | 1 | Same
A2 | A | 2 | Same
B1 | B | 1 | Same1
B2 | B | 2 | Same1
C1 | C | 1 | Diff1
C2 | C | 2 | Diff2 <---This field contains multiple values
我经常需要拉出唯一的Group
ID列表,但要求通常也需要Group_Desc
字段。 不幸的是,由于上游数据输入限制不佳,该描述字段可能在每个Group
包含多个条目,这会导致重复,因为在大多数数据提取中,“ Group
字段应唯一。 就我的目的而言,我并不在乎我可以拉哪个Group_Desc
记录,只要我可以保持1 Group
与1 Group_Desc
的关系Group_Desc
。
每当需要在较大的查询中引用Group_Desc
字段时,我都会提出一个丑陋的解决方案,称为Inline View
, Group_Desc
性能:
SELECT Group, Group_Desc
FROM Table t
WHERE Subgroup = (SELECT MIN(Subgroup)
FROM Table
WHERE Group = t.Group) --Nasty Correlated Subquery
题
有没有人有一个性能友好的窍门,可以在同一查询中重复拉回多个值的单行? 我希望能够撤回Group
并仅Group_Desc
出现的第一个Group_Desc
。
我正在设想这样的事情:
SELECT Group, Group_Desc
FROM Table t
GROUP BY Group, Group_Desc
HAVING ROWNUM = [The lowest returned Rownum within the same Group]
一位开发人员提到RANK
函数是一种可能的解决方案,但我不知道如何使用它来消除值。
您能提供的任何帮助将不胜感激!
- - - - - - - - 编辑 - - - - - - - - - - -
因此,经过一些额外的分析,我能够指出我的原始相关子查询中的一个遗漏,该遗漏导致执行计划的时间过长。 通过添加一些其他谓词,Optimizer可以创建一个更好的计划,将我的执行时间从大约12分钟更改为2分钟,这与我的期望相符。
我对Ponder Stibbons下面建议的Google Analytics(分析)解决方案做了很多实验。 他的解决方案非常优雅,我选择了该问题的答案,但是,由于执行时间比我的原始解决方案慢得多,主要是由于我能够在索引中使用索引,因此我无法在特定查询中使用它相关子查询。
我毫不怀疑,通过公平的比较,Google Analytics(分析)解决方案可以在同等条件下运行,或者比Correlated SubQuery解决方案更好。 感谢大家在这个问题上的协助!
您可以在此处在分析版本中使用min
,速度很快:
select
TGroup,
min(Group_Desc) over (partition by tgroup)
from t
first_value
也是选项:
select TGroup,
first_value(Group_Desc) over (partition by tgroup order by subgroup) gd
from t
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.