表:
UserId, Value, Date.
我想获得UserId,为每个UserId的最大值(日期)的值。也就是说,具有最新日期的每个UserId的值。有没有一种方法可以在SQL中简单地做到这一点?(最好是Oracle)
更新:为任何歧义道歉:我需要得到所有的用户id。但是对于每个UserId,只有该用户拥有最新日期的行。
表:
UserId, Value, Date.
我想获得UserId,为每个UserId的最大值(日期)的值。也就是说,具有最新日期的每个UserId的值。有没有一种方法可以在SQL中简单地做到这一点?(最好是Oracle)
更新:为任何歧义道歉:我需要得到所有的用户id。但是对于每个UserId,只有该用户拥有最新日期的行。
当前回答
在Oracle 12c+中,你可以使用Top n查询和分析函数排名来实现这一点,而且不需要子查询:
select *
from your_table
order by rank() over (partition by user_id order by my_date desc)
fetch first 1 row with ties;
上面的代码返回每个用户my_date最大的所有行。
如果你只想要一个最大日期的行,那么用row_number替换秩:
select *
from your_table
order by row_number() over (partition by user_id order by my_date desc)
fetch first 1 row with ties;
其他回答
我认为你应该对之前的查询进行修改:
SELECT UserId, Value FROM Users U1 WHERE
Date = ( SELECT MAX(Date) FROM Users where UserId = U1.UserId)
Select
UserID,
Value,
Date
From
Table,
(
Select
UserID,
Max(Date) as MDate
From
Table
Group by
UserID
) as subQuery
Where
Table.UserID = subQuery.UserID and
Table.Date = subQuery.mDate
难道一个qualified子句不是既简单又最好吗?
select userid, my_date, ...
from users
qualify rank() over (partition by userid order by my_date desc) = 1
对于上下文,在Teradata这里一个像样的大小测试运行在17秒与这个合格版本和在23秒与“内联视图”/Aldridge解决方案#1。
我已经很晚了,但下面的黑客将超越相关子查询和任何分析功能,但有一个限制:值必须转换为字符串。所以它适用于日期,数字和其他字符串。代码看起来不太好,但执行配置文件很棒。
select
userid,
to_number(substr(max(to_char(date,'yyyymmdd') || to_char(value)), 9)) as value,
max(date) as date
from
users
group by
userid
这段代码运行良好的原因是它只需要扫描表一次。它不需要任何索引,最重要的是,它不需要像大多数分析函数那样对表进行排序。如果您需要为单个用户id过滤结果,索引将有所帮助。
select UserId,max(Date) over (partition by UserId) value from users;