簡體   English   中英

在Oracle中選擇組的前n個元素

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM