我有两个表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;
与其他一些答案一样,两次读取tab2
表是低效且无必要的。你可以使用通常被称为MAX..KEEP
的东西,但是有什么令人困惑的记录为FIRST
函数(here)。
此查询使用该功能为您提供所需的结果:
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
的索引不太可能有足够的选择性来帮助,但在其他情况下要记住这一点。您是否需要加入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
选项tab2.gender,tab1.salary,tab1.emp_id,tab2.first_name来自tab1加入tab2 on tab1.emp_id = tab2.emp_id where tab1.salary =(从tab1中选择max(tab1.salary))
你能指出你想要的预期结果吗,我不清楚。 你想得到这样的东西吗? 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;