1

早上好!我正在寻找一种技巧来维护可能发生一对多关系的唯一键列表。

问题

我正在使用一个可怕的非标准化数据库,不幸的是,重新设计是不可能的。我有一个 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

我经常需要提取一个唯一的GroupID 列表,但要求通常Group_Desc也需要该字段。不幸的是,由于上游数据输入限制不佳,此描述字段可能包含多个条目,Group这会导致重复,因为该Group字段在大多数数据提取中应该是唯一的。Group_Desc出于我的目的,只要我能保持 1Group对 1的关系,我并不真正关心我拉哪条记录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出现第一个。

我正在设想这样的事情:

SELECT Group, Group_Desc
FROM Table t
GROUP BY Group, Group_Desc    
HAVING ROWNUM = [The lowest returned Rownum within the same Group]

一位开发人员提到该RANK函数是一种可能的解决方案,但我不知道如何使用它来消除值。

您能提供的任何帮助将不胜感激!

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

因此,经过一些额外的分析,我能够指出我原来的相关子查询中的一个遗漏,这导致了一个过长的执行计划。通过添加一些额外的谓词,优化器能够创建一个更好的计划,将我的执行时间从大约 12 分钟更改为 2 分钟,这符合我的预期。

我对 Ponder Stibbons 下面建议的 Analytics 解决方案做了很多试验。他的解决方案非常优雅,我选择作为这个问题的答案,但是,我无法在这个特定查询中使用它,因为执行时间比我的原始解决方案慢得多,主要是因为我能够在我的相关子查询。

我毫不怀疑,在公平的比较中,Analytics 解决方案的运行与 Correlated SubQuery 解决方案相当或更好。感谢大家对这个问题的帮助!

4

1 回答 1

1

您可以min在此处使用分析版本,它很快:

select 
    TGroup, 
    min(Group_Desc) over (partition by tgroup) 
  from t

SQLFiddle 演示

first_value也是选项:

select TGroup,
    first_value(Group_Desc) over (partition by tgroup order by subgroup) gd
  from t
于 2015-05-06T13:21:55.320 回答