2

我有一个 Oracle 表,它有一个名称、值、时间列。基本上,该表用于记录对特定名称所做的更改、以前的值是什么以及更改的时间。

我需要制定一个查询来获取特定名称的前 n 个更改,并且输出应该包含表中的所有名称。有什么帮助/建议吗?

编辑:

名称 价值 时间
Harish Pass 2011 年 11 月 1 日
拉维失败 2011 年 11 月 2 日
Harish 缺席 2011 年 10 月 31 日
Harish 于 2011 年 8 月 31 日出席
Harish 现在 2011 年 7 月 31 日

我需要在 11 月 1 日、10 月 31 日、8 月 31 日和 Ravi 选择 Harish 的详细信息。

4

5 回答 5

6

这就是你所追求的吗?

我的测试设置:

SQL> alter session set nls_date_format = 'DD-Mon-YYYY HH24:Mi:SS';

Session altered.

SQL> drop table so_test;

Table dropped.

SQL> create table so_test  (
  2    n varchar2(32)
  3  , v varchar2(32)
  4  , t date );

Table created.

SQL> 
SQL> insert into so_test values ( 'X' , 'Test1', to_date('01-Jan-2011 12:00:00','DD-Mon-YYYY HH24:Mi:SS') );

1 row created.

SQL> insert into so_test values ( 'X' , 'Test2', to_date('01-Jan-2011 13:00:00','DD-Mon-YYYY HH24:Mi:SS') );

1 row created.

SQL> insert into so_test values ( 'X' , 'Test3', to_date('01-Jan-2011 14:00:00','DD-Mon-YYYY HH24:Mi:SS') );

1 row created.

SQL> insert into so_test values ( 'Y' , 'Test5', to_date('02-Jan-2011 12:00:00','DD-Mon-YYYY HH24:Mi:SS') );

1 row created.

SQL> insert into so_test values ( 'Y' , 'Test6', to_date('03-Jan-2011 12:00:00','DD-Mon-YYYY HH24:Mi:SS') );

1 row created.

SQL> insert into so_test values ( 'Y' , 'Test7', to_date('04-Jan-2011 12:00:00','DD-Mon-YYYY HH24:Mi:SS') );

1 row created.

SQL> 

这是查询:

SQL> select n,v,t from (
  2  select n, v , t , rank() over ( partition by n order by t desc) r
  3  from so_test
  4  ) where r <= 2;

N                V                T
-------------------------------- -------------------------------- --------------------
X                Test3                01-Jan-2011 14:00:00
X                Test2                01-Jan-2011 13:00:00
Y                Test7                04-Jan-2011 12:00:00
Y                Test6                03-Jan-2011 12:00:00

SQL> 
于 2011-11-01T05:51:54.680 回答
2
select * from (select name, value, 
time, ROW_NUMBER OVER (PARTITION BY name ORDER BY name) change_no
from table )
where change_no <= 100 AND name ="abc"
ORDER BY TIME

假设名称保持不变,并对“值”进行更改。

于 2011-11-01T05:44:11.380 回答
0
select name, VALUE, TIMESTAMP 
from (select name, VALUE, TIMESTAMP, rank() over (partition by NAME order by TIMESTAMP DESC) rank 
     from logs) 
where rank <= 3
于 2011-11-01T05:53:45.287 回答
0

马修沃森的回答并不总是有效的,如果排序列重复,查询返回多于“r”行。解决方案是将唯一值连接到排序列,它可以用作表的主键。例子:

SELECT * FROM (
  SELECT 
      t.*,
      RANK() OVER (PARTITION BY object_type ORDER BY (to_char(created,'YYYYMMDDHH24MISS') || object_id) DESC) rank
    FROM ALL_OBJECTS t
    ) 
    WHERE rank <= 3
于 2013-01-14T17:05:48.940 回答
0

我提供我的快速解决方案。此查询按降序分组和计数(在内部查询中)。外部查询只允许您定义要显示的行数 (:pRows)。

Select * from
(Select
     group_field,
     count(*) Cnt
From
     record_source(s)
Where
     Conditions
Order by
     Count(*) Desc) x
Where
  rownum < :pRows+1;
于 2014-03-26T21:14:59.710 回答