Выбор первых n элементов группы в Oracle - PullRequest
2 голосов
/ 01 ноября 2011

У меня есть таблица Oracle, в которой есть столбцы с именем, значением и временем. В основном, эта таблица предназначена для ведения журнала для хранения изменений, внесенных в конкретное имя, предыдущего значения и времени внесения изменений.

Мне нужно сформулировать запрос, чтобы получить первые n изменений для определенного имени, и вывод должен содержать все имена в таблице. Любая помощь / предложения?

Edit:

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

Мне нужно выбрать подробности о Харише 1 ноября, 31 октября, 31 августа и Рави.

Ответы [ 5 ]

5 голосов
/ 01 ноября 2011

Это то, что вы ищете?

Моя тестовая установка:

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> 
1 голос
/ 01 ноября 2011
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 голосов
/ 27 марта 2014

Я предлагаю мое быстрое решение.Этот запрос группируется и учитывается в порядке убывания (во внутреннем запросе).Внешний запрос просто позволяет вам определить количество отображаемых строк (: pRows).

Select * from
(Select
     group_field,
     count(*) Cnt
From
     record_source(s)
Where
     Conditions
Order by
     Count(*) Desc) x
Where
  rownum < :pRows+1;
0 голосов
/ 14 января 2013

Ответ Мэтью Уотсона не всегда действителен, если столбец порядка дублирован, запрос возвращает больше, чем «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 голосов
/ 01 ноября 2011
select name, VALUE, TIMESTAMP 
from (select name, VALUE, TIMESTAMP, rank() over (partition by NAME order by TIMESTAMP DESC) rank 
     from logs) 
where rank <= 3
...