Oracle分组依据,从非分组列中获取第一个元素

Oracle分组依据,从非分组列中获取第一个元素,oracle,group-by,aggregate,Oracle,Group By,Aggregate,我是Oracle的新手,最近遇到了一个问题: 我有一个包含以下列的表:person\u id、account\u login、add\u date person_id | account_login | add_date ----------|---------------|------------ 1 | user1 | 2012-07-10 1 | user2 | 2012-07-09 2 | user3

我是Oracle的新手,最近遇到了一个问题:

我有一个包含以下列的表:person\u id、account\u login、add\u 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
一个人可以有多个帐户登录。对于每个人,我都要获取最早的帐户\u登录:

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)

您可以单独使用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;

不确定你认为哪个版本更优雅。如果您在同一日期为某个特定的个人id创建了两个帐户,那么它也不能解决该怎么办。如果您的添加日期中也有时间部分,那么您应该没事。如果可能出现关系,那么ROW_NUMBER()可能会给您带来更理想的结果。

您可以像这样连接表和嵌套视图

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)

顺便说一句,我真的不认为这是明确的。

谢谢!这正是我想要的。我认为它比我更优雅,因为没有任何部分是没有意义的(不像我的查询)。是的,有时间成分。因此,这将很好地工作。对不起,我忘了说:)