Как я могу выбрать first_name, максимальную группу зарплаты по полу? - PullRequest
0 голосов
/ 20 апреля 2019

У меня есть две таблицы tab1 и tab2.

create table tab1 ( emp_id number(2), salary number(4));

insert into tab1 values(1,2000); 
insert into tab1 values(2,3000); 
insert into tab1 values(3,3645); 
insert into tab1 values(4,2143); 
insert into tab1 values(5,2541);

create table tab2( emp_id number(2), first_name varchar2(20), gender varchar2(10) );

insert into tab2 values(1,'aaaa','male'); 
insert into tab2 values(2,'bbbb','female'); 
insert into tab2 values(3,'cccc','male'); 
insert into tab2 values(4,'dddd','female'); 
insert into tab2 values(5,'eeee','male');

В этом запросе я могу получить только столбцы с указанием пола и максимальной зарплаты, но я хочу видеть также столбцы emp_id и first_name.Вот мой запрос ...

select m.gender,max(h.salary) 
  from tab2 m 
  join tab1 h 
    on m.emp_id=h.emp_id 
 group by m.gender;

Ответы [ 4 ]

2 голосов
/ 21 апреля 2019

Неэффективно и не нужно читать таблицу 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

Преимущества этого альтернативного подхода:

  1. меньше повторений синтаксиса MAX..KEEP, что может стать обременительным, если вы хотите не просто emp_id и first_name, но также и куча других столбцов
  2. , он может получить выгоду от индексов, которые помогают в запросе в CROSS APPLY.В вашем случае индекс на GENDER вряд ли будет достаточно избирательным, чтобы помочь, но об этом следует помнить в других ситуациях.
2 голосов
/ 20 апреля 2019

Не могли бы вы присоединиться к saubquery для максимального количества соли и пола

select  t1.emp_id, , t2.first_name, t.max_sal, t.gender 
from  tab1 t1 
inner join  tab2 t2 on t1.emp_id = t2.emp_id 
inner join  (
  select m.gender,max(h.salary) max_sal
  from tab2 m 
  join tab1 h on m.emp_id=h.emp_id 
  group by m.gender

) t on t.max_sal = t1.salary  and t.gender = t2.gender 
0 голосов
/ 22 апреля 2019

выберите tab2.gender, tab1.salary, tab1.emp_id, tab2.first_name из tab1 присоединитесь к tab2 на tab1.emp_id = tab2.emp_id где tab1.salary = (выберите макс (tab1.salary) из tab1)

введите описание изображения здесь

0 голосов
/ 20 апреля 2019

Можете ли вы указать ожидаемый результат, который вы ищете, я не совсем уверен в этом.

Вы хотите получить что-то подобное?
emp_id, first_name, зарплата, пол

Запрос на получение всех столбцов, упорядоченных по зарплате

select h.emp_id, m.first_name, m.gender,h.salary from tab2 m join tab1 h on m.emp_id=h.emp_id order by h.salary desc;
...