[英]Selecting top n elements of a group in Oracle
我有一个包含名称,值,时间列的Oracle表。基本上,该表用于记录目的,用于存储对特定名称所做的更改,先前的值是什么以及更改时间。
我需要制定一个查询来获取特定名称的前n个更改,并且输出应具有表中的所有名称。 任何帮助/建议吗?
编辑:
Name Value Time Harish Pass 1-Nov-2011 Ravi Fail 2-Nov-2011 Harish Absent 31-Oct-2011 Harish Attended 31-Aug-2011 Harish Present 31-Jul-2011
我需要选择11月1日,10月31日,8月31日和Ravi的Harish详细信息。
这是你所追求的吗?
我的测试设置:
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>
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
假设名称保持不变,并且对“值”进行了更改。
马修·沃森(Matthew Watson)的答案并不总是有效的,如果重复订购列,则查询返回的行将超过“ 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
我提供我的快速修复。 该查询以降序分组和计数(在内部查询中)。 外部查询仅允许您定义要显示的行数(:pRows)。
Select * from
(Select
group_field,
count(*) Cnt
From
record_source(s)
Where
Conditions
Order by
Count(*) Desc) x
Where
rownum < :pRows+1;
select name, VALUE, TIMESTAMP
from (select name, VALUE, TIMESTAMP, rank() over (partition by NAME order by TIMESTAMP DESC) rank
from logs)
where rank <= 3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.