我对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)
答案 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)
顺便说一句,我真的不认为这很清楚。