0

我需要mytable在 Oracle v11.2 中为给定的一对列选择最后一行:

id    type     timestamp     raw_value     normal_value
--    ----     ---------     ---------     ------------
1     3        3pm 3-Jun     "Jon"         "Jonathan"
1     3        5pm 3-Jun     "Jonathan"    "Jonathan"
1     3        2pm 4-Jun     "John"        "Jonathan"
1     3        8pm 6-Jun     "Bob"         "Robert"
1     5        6pm 3-Jun     "NYC"         "New York City"
1     5        7pm 5-Jun     "N.Y.C."      "New York City"
4     8        1pm 1-Jun     "IBM"         "International Business Machines"
4     8        5pm 8-Jun     "I.B.M."      "International Business Machines"

我认为查询将是这样的:

SELECT raw_value, normal_value, MAX(timestamp)
  FROM mytable
  WHERE id = 1 and type = 3
  GROUP BY id, type

对于上述情况,这应该给我:

“鲍勃”、“罗伯特”,6 月 6 日晚上 8 点

我实际上并不需要timestamp我的答案,而只需要它为给定的id和最大的选择匹配的行。typetimestamp

我的方法是否适用于 Oracle v11.2,如果可以,是否有办法timestamp从选定的列中省略,因为我实际上并不需要它的值?

4

4 回答 4

4

您可以使用以下row_number()功能执行此操作:

select raw_value, normal_value, timestamp
from (select myt.*, ROW_NUMBER() over
           (partition by id, type order by timestamp desc)
      as seqnum
      from mytable myt
     ) tmp
where seqnum = 1
and id = 1 and type = 3;

row_number()是一个分析函数(又名窗口函数),它将序号分配给行。定义的每个组id, type都有自己的编号。第一行是具有最新时间戳 ( order by timestamp desc) 的行。外部选择子句select中的这一行。where

在平局的情况下,此版本仅返回一行。要获取所有行,请使用rank()而不是row_number().

于 2013-06-05T15:03:46.727 回答
1

尝试这个:

SELECT m1.raw_value, m1.normal_value
FROM mytable m1
WHERE id = 1 and type = 3 and timestamp = (
    SELECT MAX(timestamp)
    FROM mytable m2
    WHERE m1.id = m2.id and m1.type = m2.type
    GROUP BY m2.id, m2.type
)
于 2013-06-05T15:03:59.730 回答
0

尝试

select max(raw_value ) keep (dense_rank last order by timestamp),
max(normal_value ) keep (dense_rank last order by timestamp)
from mytable
WHERE id = 1 and type = 3
于 2013-06-05T16:17:54.150 回答
0

您可以使用 Oracle 分析 RANK 函数确定最近的时间戳,如下所示:

SELECT
  raw_value,
  normal_value,
  RANK() OVER (ORDER BY timestamp DESC) as TimestampRank
FROM myTable

这将为TimestampRank具有最高时间戳的行设置值为 1 的列。如果最高时间戳平分,则所有具有最高时间戳的行都TimestampRank设置为 1。

要获得"Bob", "Robert",请用一个外部查询包围上面的查询,该查询仅选择那些列和过滤器TimestampRank = 1

SELECT raw_value, normal_value
FROM (
  SELECT
    raw_value,
    normal_value,
    RANK() OVER (ORDER BY timestamp DESC) as TimestampRank
  FROM myTable
)
WHERE TimestampRank = 1

再次注意,如果最高时间戳存在平局,则将返回具有该值的所有行。如果您总是想要一行而不考虑平局,请在上面的查询中使用ROW_NUMBER()而不是。RANK()

于 2013-06-05T15:05:16.547 回答