2011-11-01 2 views
2

이름, 값, 시간 열이있는 Oracle 테이블이 있습니다. 기본적으로 테이블은 특정 이름의 변경 사항을 저장하기 위해 로깅 용입니다. 가치와 변화가 발생한 시간.Oracle에서 그룹의 상위 n 요소를 선택하십시오

특정 이름에 대한 상위 n 개의 변경 사항을 가져 오는 쿼리를 공식화해야하며 출력에는 테이블의 모든 이름이 있어야합니다. 도움/아이디어?

편집 : 내가 11월 1일 10 월 31 일, 31 년 8 월과 라비에 Harish의 세부 사항을 선택해야

 
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 

.

+0

"상위 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

여기에 솔루션 선택 이름 인 VALUE, TIMESTAMP (이름 선택, VALUE, TIMESTAMP, rank (over) (TIMESTAMP DESC에 의한 NAME 주문 별 파티션) 로그에서 순위) 여기서 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

날짜를 연결하거나 문자열로 변경할 필요가 없습니다. 'order by created, 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; 
관련 문제