我有两个表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;
答案 0 :(得分:2)
您是否需要在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
答案 1 :(得分:2)
像其他一些答案一样,两次读取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
上的索引可能没有足够的选择性来提供帮助,但是在其他情况下要牢记这一点。答案 2 :(得分:0)
从tab1中选择tab2.gender,tab1.salary,tab1.emp_id,tab2.first_name加入tab1上的tab2.emp_id = tab2.emp_id其中tab1.salary =(从tab1中选择max(tab1.salary))
答案 3 :(得分:-2)
能否请您指定所需的预期结果,我不清楚。
你想得到这样的东西吗?
emp_id,名字,工资,性别
查询以按薪水排序的所有列
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;