При написании запроса, такого же сложного, как и в вашем вопросе, очень легко ошибиться (или два). Поскольку у нас нет реальных данных об отдыхе, я бы скорее дал вам упрощенный пример, который - когда вы применяете принципы, представленные к вашему собственному запросу - должен позволить вам найти правильное решение самостоятельно. Как предложил @Vivek, использование аналитических функций (см. документация и примеры ) было бы способом получить необходимый набор результатов.
Тестовые таблицы
-- helper table
create table T
as
select
level as companyid
from dual
connect by level <= 4 ;
-- table used for queries
create table T2
as
select
A.companyid
, trunc( dbms_random.value * 1000 ) as amount
, to_date( trunc( dbms_random.value( 2446081, 2458243 ) ), 'J' ) paymentdate
from T A, T B ;
Данные
SQL> select * from T2 order by companyid, paymentdate desc ;
COMPANYID AMOUNT PAYMENTDATE
1 766 27-MAY-95 -- <- required
1 198 12-APR-90
1 554 05-AUG-89
1 82 27-FEB-87
2 195 07-AUG-07 -- <- required
2 623 07-OCT-03
2 903 01-NOV-93
2 519 09-NOV-88
3 561 27-JUN-97 -- <- required
3 335 05-SEP-92
3 327 25-JAN-87
3 967 04-AUG-85
4 623 10-APR-17 -- <- required
4 912 24-FEB-12
4 385 08-APR-01
4 708 10-MAR-87
16 rows selected.
Проблема в том, что мы хотим, чтобы последняя ОПЛАТА, включая СУММУ, для каждой КОМПАНИИ - что-то вроде следующего запроса, который НЕ работает ...
select
companyid
, max( paymentdate )
, amount -- cannot get the amount of the last payment(date)
from T2
group by companyid ;
-- ORA-00979: not a GROUP BY expression
Если мы теперь добавим больше столбцов в предложение GROUP BY, мы получим слишком много групп (как это было бы). Это произошло с вами, когда вы только что добавили столбец AMOUNT в предложения SELECT и GROUP BY.
-- if we code
-- ... group by companyid, paymentdate, amount
-- then we get all rows (again) -> no use
select
companyid
, max( paymentdate )
, amount
from T2
group by companyid, paymentdate, amount ;
-- 16 rows selected. (output omitted)
Использование аналитических функций позволяет нам «группировать» строки другим способом, записывая (разбиение по ...). Обратите внимание, что предложение GROUP BY отсутствует в этом запросе. Мы получаем необходимые ДАТЫ ОПЛАТЫ и т. Д.
select distinct
companyid
, max( paymentdate ) over ( partition by companyid ) mostrecentpayment
, first_value( amount ) over ( partition by companyid order by paymentdate desc ) amount
from T2
order by companyid ;
-- result
COMPANYID MOSTRECENTPAYMENT AMOUNT
1 27-MAY-95 766
2 07-AUG-07 195
3 27-JUN-97 561
4 10-APR-17 623
Используя подход @ Vivek, для той же тестовой таблицы (набор результатов такой же, как указано выше):
select
companyid
, paymentdate
, amount
from (
select
companyid
, paymentdate
, rank() over ( partition by companyid order by paymentdate desc ) rank_
, amount
from T2
) where rank_ = 1 ;
COMPANYID PAYMENTDATE AMOUNT
1 27-MAY-95 766
2 07-AUG-07 195
3 27-JUN-97 561
4 10-APR-17 623
Протестировано с Oracle 12c. Примечание: значения в T2 являются случайными!