Oracle group by,从非分组列中获取第一个元素

时间:2012-07-13 20:39:02

标签: oracle group-by aggregate

我对Oracle很陌生,最近我遇到了一个问题:

我有一个包含以下列的表:person_id,account_login,add_date。

person_id | account_login | add_date
----------|---------------|------------
1         | user1         | 2012-07-10
1         | user2         | 2012-07-09
2         | user3         | 2012-07-05
2         | user4         | 2012-07-04

一个人可以拥有多个account_logins。对于每个人,我想获取最旧的account_login:

person_id | account_login | add_date
----------|---------------|------------
1         | user2         | 2012-07-09
2         | user4         | 2012-07-04

所以我做的是:

select
  person_id,
  MAX(account_login) KEEP (DENSE_RANK FIRST ORDER BY add_date)
from
  table
group by
  person_id;

我得到了我想要的结果,但我认为我的查询的语法远非好.Oracle迫使我使用聚合函数,我使用MAX()或MIN()知道它的结果完全没意义..

有没有办法比这更好地编写查询? (Oracle 11g)

2 个答案:

答案 0 :(得分:2)

您可以单独使用DENSE_RANK作为分析,并从结果查询中选择:

SELECT person_id, account_login, add_date
  FROM (SELECT table.*
             , DENSE_RANK() OVER (PARTITION BY person_id ORDER BY add_date) rnk
         FROM table)
 WHERE rnk = 1;

不确定您认为哪个版本更优雅。如果您在特定person_id的同一日期创建了两个帐户,它也无法解决该怎么做。如果你在add_date中也有一个时间组件,那么你应该没问题。如果可能存在关联,或许ROW_NUMBER()会给你一个更理想的结果。

答案 1 :(得分:0)

您可以像这样加入表格和嵌套视图

select person_id,account_login,add_date
from tab inner join 
(select person_id,min(add_date) add_date 
from tab group by person_id) 
using(person_id,add_date)
顺便说一句,我真的不认为这很清楚。