Запрос Oracle должен вернуть самую высокую дату из результата - PullRequest
1 голос
/ 15 декабря 2010

У меня действительно большой запрос, из-за которого у меня возникают проблемы, потому что одно соединение может вернуть несколько строк. Мне нужна только последняя строка (определенная полем даты) в этом наборе результатов, но я не могу собрать правильный запрос, чтобы он работал.

Запрос, который мне нужен, МАКСИМАЛЬНАЯ дата от:

SELECT custid,reason,date FROM OPT opt WHERE opt.custid = 167043;

Custid действительно можно найти с помощью объединения, но для простоты я добавил его в предложение where. Этот запрос дает следующий результат:

custid    grunn       date
167043  "Test 1"    19.10.2005 12:33:18
167043  "Test 2"    28.11.2005 16:23:35
167043  "Test 3"    14.06.2010 15:43:16

Как я могу получить только одну запись из этого набора результатов? И эта запись с самой высокой датой? В конечном счете, я помещаю это в большой запрос, который выполняет много объединений, так что, надеюсь, я смогу использовать этот пример в своем большем запросе.

Ответы [ 5 ]

1 голос
/ 15 декабря 2010

Вы можете сделать это:

SELECT * FROM
( SELECT custid,reason,date FROM OPT opt WHERE opt.custid = 167043
  ORDER BY date DESC
) 
WHERE ROWNUM = 1;
1 голос
/ 15 декабря 2010

Вы можете решить это с помощью аналитических функций. Попробуйте что-то вроде этого:

select custid 
      ,reason
      ,date
  from (select custid 
              ,reason
              ,date
              ,row_number() over(partition by cust_id order by date desc) as rn
         from opt)
 where rn = 1;

Вот как это работает: набор результатов делится на группы cust_id (partition by). В каждой группе строки будут отсортированы по столбцу даты в порядке убывания (order by). Каждой строке в группе будет присвоен порядковый номер (row_number) от 1 до N. Таким образом, строке с наибольшим значением даты будет присвоен 1, второй последний 2, третий последний 3 и т. Д.

Наконец, я просто выбираю строки с nr = 1, что в основном отфильтровывает другие строки.

0 голосов
/ 15 декабря 2010

оба решения с ROW_NUMBER и KEEP хороши. Я бы предпочел ROW_NUMBER при извлечении большого количества столбцов и оставить KEEP для одного или двух столбцов, в противном случае вам придется иметь дело с дубликатами, и утверждение станет довольно нечитаемым.

Однако для небольшого числа столбцов KEEP должен работать лучше

0 голосов
/ 15 декабря 2010

вместо использования row_number () Я думаю, что лучше выбрать то, что вы на самом деле хотите выбрать (например, последнюю дату)

SELECT custid
,      reason
,      date
from
(
    SELECT custid
    ,      reason
    ,      date
    ,      max(opt.date) over (partition by opt.custid order by opt.date) last_date 
    FROM   OPT opt 
    WHERE  opt.custid = 167043;
)
where  date = last_date
0 голосов
/ 15 декабря 2010

Или другим способом, используя функцию LAST в ее агрегированной форме.

with my_source_data as (
  select 167043 as custid, 'Test 1' as reason, date '2010-10-01' as the_date from dual union  all
  select 167043 as custid, 'Test 2' as reason, date '2010-10-02' as the_date from dual union  all
  select 167043 as custid, 'Test 3' as reason, date '2010-10-03' as the_date from dual union  all
  select 167044 as custid, 'Test 1' as reason, date '2010-10-01' as the_date from dual
)
    select 
      custid,
      max(reason) keep (dense_rank last order by the_date) as reason,
      max(the_date)
    from my_source_data
    group by custid

Я нахожу это весьма полезным, поскольку он объединяет процесс поиска последней строки и значения в одну. Использование MAX (или другой агрегатной функции, такой как MIN) в случае, если комбинация группировки и порядка по не является детерминированной.

Эта функция в основном будет принимать содержимое столбца на основе группировки, упорядочивать его по заданному порядку, а затем принимать последнее значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...