Oracle - выберите последнюю отдельную запись из таблицы - PullRequest
2 голосов
/ 21 марта 2012

Теоретически это кажется простым, но я просто не могу разобраться с этим ...

Вот мои данные таблицы и данные

ID    Heading    Date         Row_Num
 1       Test    12-MAR-12          1
 1      Test2    13-MAR-12          2
 2      Test3    13-MAR-12          3

А вот мой запрос

select * from 
table1 
where date <= :date 
order by date desc

:date, например, 14-MAR-12

Это, очевидно, дает все три результата, но я хочу получить из этого запроса следующие данные

ID    Heading    Date         Row_Num
 1      Test2    13-MAR-12          2
 2      Test3    13-MAR-12          3

ИтакЯ добавил distinct, но это работает не так, как ожидалось, поскольку мне приходится группировать по каждому столбцу, и при этом он по-прежнему дает 3 результата.

Любые идеи о том, как я могу добиться результата, я 'м после?

Ответы [ 3 ]

4 голосов
/ 21 марта 2012

Вам нужно будет использовать аналитическую функцию. Функция row_number должна помочь.

select *
from
(
    select 
        id,
        heading,
        date,
        row_number() over ( partition by id order by heading desc nulls last ) r
    from table1
)
where r = 1

Аналитические функции могут использоваться для выполнения анализа и группировки строк в наборе результатов. В приведенном выше примере inner-select запрашивает table1 как обычно. Функция row_number () будет сравнивать каждую строку с другими возвращенными строками (используя агрегат, предоставленный в операторе разделения), чтобы получить число. В этом случае мы группируемся по ID и упорядочиваем по убыванию. У external-select есть предложение where, которое отфильтровывает строки, у которых номер строки не равен 1. Запустите только inner-select, чтобы увидеть, как все это работает.

3 голосов
/ 21 марта 2012

Если вам просто нужна строка с самой последней DT для каждого ID, вам нужно что-то вроде

SELECT id,
       heading,
       dt
  FROM (SELECT id,
               heading,
               dt,
               ROW_NUMBER() OVER (PARTITION BY id
                                      ORDER BY dt desc) rnk
          FROM table1)
 WHERE rnk = 1

Если возможны связи (две строки с одинаковыми ID и DT, вы можете захотеть добавить что-то еще к ORDER BY в аналитической функции, которая детерминистически разрывает связь, а не позволяет Oracle нарушать ее произвольно.

1 голос
/ 22 марта 2012

Я мог бы неправильно понять, чего вы хотите достичь, но я думаю, что вы можете сделать это с помощью группы и подзапроса, следующим образом:

SELECT * 
FROM table1 
WHERE ID||date IN 
  (SELECT ID||MAX(date)
  FROM table1 
  WHERE date <= to_date('14-mar-12', 'DD-mon-YY') 
  GROUP BY ID
  );

Это даст вам одну строку на ID и дату, если не существует нескольких строк с одинаковым идентификатором и одинаковой датой.

...