2011-11-01 85 views
2

我有一個Oracle表,它具有名稱,值和時間列。基本上,該表用於記錄目的以存儲對特定名稱所做的更改,以前是價值和變更的時間。在Oracle中選擇組中的前n個元素

我需要制定一個查詢來獲取特定名稱的前n個變化,並且輸出應該包含表中的所有名稱。 任何幫助/ suggesstions?

編輯:

 
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日和拉維哈里什的細節。

+0

你如何定義「前n個變化」?你的意思是「最近n次變化」? –

+0

你能舉一個你想要的例子嗎? –

+0

@robmayoff是的,我的意思是最近的變化,第三列是時間欄,它存儲了更改的時間 – Harish

回答

4

這是你在追求什麼?

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> 
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> 
+0

感謝您的努力。 – Harish

1
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 

假設名稱保持不變,並且對「值」進行了更改。

+0

謝謝我已經得到了解決方案,我沒有嘗試解決方案。更新瞭解決方案。 – Harish

+0

這裏是解決方案select name,VALUE,TIMESTAMP from(選擇名稱,VALUE,TIMESTAMP,rank()over(由TIMESTAMP DESC按NAME排序的分區)rank from rank)其中rank <= 3 – Harish

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 
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 
+0

不需要連接或甚至將日期更改爲字符串。 '通過創建,object_id'的順序會很好 –

0

我提供了我的快速解決方案。此查詢按降序(在內部查詢中)進行分組和計數。外部查詢只允許您定義要顯示的行數(:pRows)。

Select * from 
(Select 
    group_field, 
    count(*) Cnt 
From 
    record_source(s) 
Where 
    Conditions 
Order by 
    Count(*) Desc) x 
Where 
    rownum < :pRows+1;