获取具有列的最大值的行

表:

UserId, Value, Date.

我想为每个UserId获取UserId,最大值(Date)的值。 即,具有最新日期的每个用户标识的值。 有没有办法简单地在SQL中执行此操作? (最好是甲骨文)

更新:道歉的任何歧义:我需要得到所有的用户ID。 但是对于每个UserId,只有那个用户拥有最新日期的行。


这将检索my_date列值等于该用户标识的my_date的最大值的所有行。 这可能会检索多个行,其中最大日期位于多行。

select userid,
       my_date,
       ...
from
(
select userid,
       my_Date,
       ...
       max(my_date) over (partition by userid) max_my_date
from   users
)
where my_date = max_my_date

“分析函数摇滚”

编辑:关于第一条评论...

“使用分析查询和自我加入会破坏分析查询的目的”

此代码中没有自加入。 而是有一个谓词放在包含分析函数的内联视图的结果上 - 这是一个非常不同的问题,也是完全标准的实践。

“Oracle中的默认窗口是从分区的第一行到当前的一行”

窗口条款仅适用于存在order by子句的情况。 没有order by子句的情况下,默认情况下不应用窗口子句,并且可以明确指定none。

代码起作用。


我发现很多人使用子查询或其他特定于供应商的功能来执行此操作,但我通常按以下方式进行不带子查询的此类查询。 它使用普通的标准SQL,因此它应该适用于任何品牌的RDBMS。

SELECT t1.*
FROM mytable t1
  LEFT OUTER JOIN mytable t2
    ON (t1.UserId = t2.UserId AND t1."Date" < t2."Date")
WHERE t2.UserId IS NULL;

换句话说:从t1中获取行,其中不存在具有相同UserId和更大Date的其他行。

(我把标识符“Date”放在分隔符中,因为它是一个SQL保留字。)

如果t1."Date" = t2."Date" ,则会出现翻倍。 通常表具有auto_inc(seq)键,例如id 。 避免加倍可以使用如下:

SELECT t1.*
FROM mytable t1
  LEFT OUTER JOIN mytable t2
    ON t1.UserId = t2.UserId AND ((t1."Date" < t2."Date") 
         OR (t1."Date" = t2."Date" AND t1.id < t2.id))
WHERE t2.UserId IS NULL;

来自@Farhan的评论:

这里有一个更详细的解释:

外连接尝试将t2与t2连接起来。 默认情况下,返回t1的所有结果,如果在t2中有匹配,它也会返回。 如果t1的给定行在t2中没有匹配,那么查询仍返回t1的行,并将NULL用作所有t2列的占位符。 这就是外部联接的一般工作方式。

此查询中的技巧是设计连接的匹配条件,使得t2必须匹配相同的用户标识和更大的日期。 这个想法是,如果行中存在一个具有更大日期的行,那么它与t1进行比较的行不能是该userid的最大日期。 但是,如果没有匹配 - 即如果t2中没有行存在比t1中的行更大的日期 - 我们知道t1中的行是给定用户标识的日期最长的行。

在这些情况下(当没有匹配时),t2的列将为NULL - 甚至连接条件中指定的列。 所以这就是为什么我们使用WHERE t2.UserId IS NULL原因,因为我们正在寻找没有找到具有给定用户标识的更长日期的行的情况。


SELECT userid, MAX(value) KEEP (DENSE_RANK FIRST ORDER BY date DESC)
  FROM table
  GROUP BY userid
链接地址: http://www.djcxy.com/p/83721.html

上一篇: Fetch the row which has the Max value for a column

下一篇: How to do chained transitions on different elements in d3.js?