我试图通过将员工工资提高15%来修改SCOTT
架构。如果得到的薪水超过他或她的最高工资HISAL
,在SALGRADE
我们只使用HISAL
,我的代码是:
select
coalesce((
select sal*1.15
from emp , salgrade
where
sal*1.15<=hisal
) ,
(select hisal from emp ,salgrade where sal*1.15>hisal )) raised_sal
from emp ;
内部选择返回多行
有没有人有建议或不同的代码?
答案 0 :(得分:3)
如果我们打破你要做的事情:
coalesce
给出了第一个值,除非它是null然后是第二个等等。你没有指定任何连接条件,所以你在emp
和{之间进行cartesian join
{1}}。这将返回salgrade
中的行数乘以 emp
中的行数;视您的加入条件而定。
查询的第二部分在相反的方向上完全相同。
假设table_structure为:
salgrade
你想做这样的事情:
create table emp (
emp_id number
, salary number -- current salary
, salgrade_id number -- current salary grade
, dept_id -- current department
);
create table salgrade (
, salgrade_id number
, hisal number -- max salary for that grade
);
least
function与select least( e.salary * 1.15, s.hisal )
from emp e
join salgrade s
on e.salgrade_id = s.salgrade_id
类似;因为它将采取最小值。但是,它适用于同一行上的多个列,而不是同一列上的多个行。
通过min
和least
hisal
,我们确保如果加薪幅度高于salary * 1.15
,则会取代hisal
。
在这种情况下,hisal
表示对于每个join
,我们会将emp_id
用于相应的工资等级。我强烈推荐reading up on SQL joins - 这个链接在Google上排名第7,这有点令人惊讶(Jeff似乎无处不在),但它非常好并且有更多链接。
要更改查询以使您能够为所有收入超过100,000的员工(富人变得更富有)执行此操作,它将看起来像这样:
hisal
或者如果您只想为IT人员(为什么不这样做)这样做会使问题复杂化,您可以将其扩展为类似的内容:
select least( e.salary * 1.15, s.hisal )
from emp e
join salgrade s
on e.salgrade_id = s.salgrade_id
where e.salary > 100000
这些联接由select least( e.salary * 1.15, s.hisal )
from emp e
join salgrade s
on e.salgrade_id = s.salgrade_id
join dept d
on e.dept_id = d.dept_id
where d.dept = 'IT'
而不是inner joins
(通常为outer joins
- 请参阅链接)暗示每位员工都有成绩和部门。
答案 1 :(得分:1)
你应该通过 non equijoin :
加入emp与salgrade select sal*1.15
from
emp
inner join
salgrade sg
on emp.sal BETWEEN sg.losal AND sg.hisal <-- here!
where
sal*1.15<=hisal
更多信息:Introduction to Basic SQL, Part 3 - Complex Joins and Sub-queries:
“我们加入了BETWEEN运营商.SALGRADE的付款频道 table使用一系列薪水来指定成绩。“
修改强>
要计算员工等级,您应该查找员工薪水,并查看包含员工薪水的薪资范围的salgrade。
这是salgrade数据:
...
INSERT INTO SALGRADE VALUES (2,1201,1400);
INSERT INTO SALGRADE VALUES (3,1401,2000);
...
如果员工薪水是1495,那意味着他的成绩是2。
如果你以15%的比例增加1395,那么这超出你的萨拉格范围,正如你解释的那样,你应该将工资设定为1400,这是范围2的治疗。
您的查询:
select
coalesce((
select sal*1.15
from emp e2
inner join
salgrade sg
on e2.sal BETWEEN sg.losal AND sg.hisal
where
e2.EMPNO = e1.EMPNO and
sal*1.15<=hisal
) ,
(select hisal from emp e2 inner join salgrade sg
on e2.sal BETWEEN sg.losal AND sg.hisal
where e2.EMPNO = e1.EMPNO
)) raised_sal
from emp e1 ;
没有子查询:
select
case
when sal*1.15 < hisal then sal*1.15
when sal*1.15 >= hisal then hisal
end
raised_sal
from
emp e1
inner join
salgrade sg
on e1.sal BETWEEN sg.losal AND sg.hisal
免责声明,未经测试。
答案 2 :(得分:0)
我认为你错过了加入条件...
在查询中你可以给出连接条件,如果有的话(比如emp.employee_name = salgrade.employee_name)
并且还必须给出内部查询条件... 喜欢
select
coalesce((
select sal*1.15
from emp e2, salgrade
where
sal*1.15<=hisal
and e2.employee_name = e1.employee_name
) ,
(select hisal from emp e3,salgrade where sal*1.15>hisal
and e3.employee_name = e1.emplyee_name
)) raised_sal
from emp e1;