Неэффективно и не нужно читать таблицу tab2
дважды, как в некоторых других ответах.Вы можете использовать то, что обычно называют MAX..KEEP
, но то, что запутанно задокументировано как функция FIRST
( здесь ).
Этот запрос использует функцию, чтобы дать вам результатыВы ищете:
SELECT t2.gender,
max(t2.emp_id) keep ( dense_rank first order by t1.salary desc ) emp_id,
max(t2.first_name) keep ( dense_rank first order by t1.salary desc ) first_name,
max(t1.salary)
FROM tab1 t1
INNER JOIN tab2 t2 ON t2.emp_id = t1.emp_id
GROUP BY t2.gender;
Обратите внимание, что он читает каждую таблицу только один раз.
Результаты:
+--------+--------+------------+----------------+
| GENDER | EMP_ID + FIRST_NAME | MAX(T1.SALARY) |
+--------+--------+------------+----------------+
| female | 2 + bbbb | 3000 |
| male | 3 + cccc | 3645 |
+--------+--------+------------+----------------+
Я утверждаю, чтоэто самый эффективный способ получения результатов, к которым вы стремитесь.
[Мне не нравится делать подобные заявления без места для маневра (или «слов ласки», если хотите), поскольку их так много.там нам всем нужно учиться.Но, если есть более быстрый способ выполнить этот запрос, изучение его стоило бы вынести публичное исправление SO.:)]
ОБНОВЛЕНИЕ
Кстати, если бы у вас была таблица GENDERS
, как эта ...
create table genders ( gender varchar2(10) );
insert into genders values ('male');
insert into genders values ('female');
Тогда это также было бы разумным решением в12c и более поздние:
select g.gender,
ca.emp_id,
ca.first_name,
ca.salary
from genders g
CROSS APPLY ( SELECT t2.emp_id,
t2.first_name,
t2.gender,
t1.salary
FROM tab1 t1
INNER JOIN tab2 t2 on t2.emp_id = t1.emp_id
WHERE t2.gender = g.gender
ORDER BY t1.salary DESC
FETCH FIRST 1 ROW ONLY ) ca
Преимущества этого альтернативного подхода:
- меньше повторений синтаксиса
MAX..KEEP
, что может стать обременительным, если вы хотите не просто emp_id
и first_name
, но также и куча других столбцов - , он может получить выгоду от индексов, которые помогают в запросе в
CROSS APPLY
.В вашем случае индекс на GENDER
вряд ли будет достаточно избирательным, чтобы помочь, но об этом следует помнить в других ситуациях.