Макс над умножить столбцы - PullRequest
3 голосов
/ 03 февраля 2011

У меня маленькая проблема:

В моей таблице есть следующие строки:

PersHist

ID    Date         Histroy
1     01.01.2008   0
1     01.01.2008   1
1     01.01.2008   2
1     02.01.2008   0
1     02.01.2008   1

Теперь, когда я делаю выбор, например:

SELECT max(date), max(Histroy) 
FROM PersHist
WHERE ID = 1

Я получаю этот вывод:

ID    Date         Histroy
1     02.01.2008   2

Это неверно, потому что нет 02.01.2008/2 (Дата / История)

Можно ли написать простой SQL, который получит меня 02.01.2008/1 без написания подзапросов?

Ответы [ 3 ]

6 голосов
/ 03 февраля 2011

Попробуй это.Он будет принимать все записи с ID = 1, упорядочивать их по дате (от последней к самой старой), а затем по истории (по убыванию), а затем вернет вам первую запись (то есть с самой последней датой и самой высокой историей в этой дате).

SELECT * FROM 
(SELECT ID, Date, Histroy
 FROM PersHist
 WHERE ID = 1
 ORDER BY Date DESC, Histroy DESC)
WHERE ROWNUM = 1

К сожалению, он не работает без подзапроса.Oracle сначала приписывает ROWNUM, а затем ORDER s

2 голосов
/ 04 февраля 2011

Такие случаи могут быть решены без подзапросов с помощью keep (dense_rank first... "идиома":

create table tq84_pershist (
  id      number,
  dt      date,
  histroy number
);

insert into tq84_pershist values (1, date '2008-01-01', 0);
insert into tq84_pershist values (1, date '2008-01-01', 1);
insert into tq84_pershist values (1, date '2008-01-01', 2);
insert into tq84_pershist values (1, date '2008-01-02', 0);
insert into tq84_pershist values (1, date '2008-01-02', 1);

При такой «настройке» запрос выглядит так:

select max(dt     ) keep (dense_rank first order by dt desc, histroy desc) dt,
       max(histroy) keep (dense_rank first order by dt desc, histroy desc) histroy
from 
tq84_PersHist;

в результате

DT          HISTROY
-------- ----------
02.01.08          1
1 голос
/ 03 февраля 2011

Во-первых, ваш запрос работает правильно (то есть в соответствии со стандартом SQL), так как он возвращает наибольшее значение из каждого поля.То, что это не то, что вам нужно, не означает, что это неправильно ...

Чтобы сделать это без подзапроса, вам нужно использовать аналитические функции:

SELECT distinct first_value(date) over (order by date desc, history desc),
                first_value(history) over  (order by date desc, history desc) 
FROM PersHist

ОднакоМетод подзапроса обычно быстрее, особенно для больших таблиц.

...