2012-02-19 29 views
-1

我试图通过将员工薪水提高15%来修改SCOTT模式。如果得到的薪水超过了SALGRADE他或她的尽可能高的薪水,HISAL,我们只是用HISAL,我的代码是:仅使用SQL将薪水提高15%?

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

我想你只错过了加盟条件...

两个查询,你可以给连接条件,如果有的话(如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; 
+0

加入名字是一种造成非常大的错误的方法,您需要使用唯一的标识符,并且名称不保证是唯一的。当我发现38时,我厌倦了计算Pratik Garg在Facebook上注册的数量。 – Ben 2012-02-19 16:22:52

+0

这只是暗示不是一个合适的查询。 我在告诉你,因为没有子查询而得到多行异常条件.. 如果你将添加这些条件,那么你会得到单行(最有可能....如果你没有多个记录在你的表中的客户..) – 2012-02-19 18:13:20

1

你应该通过非等值连接与salgrade加入EMP:

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 表中的paybands使用范围工资指定一个档次。”

编辑

计算员工等级,你应该看员工的工资和考虑salgrade的工资范围包含员工工资

这是salgrade数据:

... 
INSERT INTO SALGRADE VALUES (2,1201,1400); 
INSERT INTO SALGRADE VALUES (3,1401,2000); 
... 

如果Employee的alary是1495,意思是他的等级是2.

如果你增加1595%的1395,那么这超出了你的salrange的范围,并且如你所解释的,你应该设置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 

声明,未经测试。

+0

但danihp它不会给hisal员工的工资值大于他的工资时的价值? 有这种情况的员工将不会成为此输出的一部分..对吗? – 2012-02-19 15:26:14

+0

查看编辑答案。 – danihp 2012-02-19 16:22:59

+0

Denihp我认为我没有正确描述那个时间......我想说的是's1.los之间和sg.hisal之间的e1.sal'这种情况不应该在那里满足这个'的第二个条件'case '句子.. 请再想一想..你一定会明白我的意思.. 顺便说一下你的查询方式很不错.. – 2012-02-19 18:04:55

3

如果我们击穿你想要做什么:

​​3210给人的第一价值,除非为null,则第二等您还没有指定任何连接条件,所以你做在empsalgrade之间的cartesian join。这将返回行数emp乘以行数salgrade;受你的加入条件。

查询的第二部分在相反的方向上完全相同。

假设的table_structure:

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 
     ); 

你想要做这样的事情:

select least(e.salary * 1.15, s.hisal) 
    from emp e 
    join salgrade s 
    on e.salgrade_id = s.salgrade_id 

least function类似于min;因为它将取最小值。但是,它可以处理同一行上的多个列,而不是同一列上的多个行。

通过采取hisalleastsalary * 1.15我们保证,如果工资的增长是高于hisal然后hisal改为使用。

在这种情况下,join意味着,每emp_id我们采取hisal为适当的薪金等级。我强烈推荐reading up on SQL joins - 这个链接在谷歌上排名第7,这有些让人吃惊(杰夫似乎无处不在),但它很不错,还有更多的链接。

更改查询,让你这样做对收入超过10万的所有员工(富者愈富),它会是这个样子:

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 

或者使问题复杂化,如果你想做到这一点仅IT人民(为什么不),你可以把它扩展到是这样的:通过被inner joins,而不是outer joins

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' 

这些连接(通常left outer joins - 见链接),意味着每一位员工有一个等级和一个部门。

+0

Ben,salgrade_id不存在。 – danihp 2012-02-19 16:28:16

+0

@danihp,没有或不能找出我必须即兴创作的模式。在'salgrade'中必须有一个唯一的标识符,在'emp'中使用这个标识符的外键,否则该模式本质上是无用的;将此标识符替换为'salgrade_id' – Ben 2012-02-19 16:30:54

+0

主要问题是要知道如何通过非等值连接将'emp'与'salgrade'连接起来。没有这个外键的话,这个模式就没有用处了。 – danihp 2012-02-19 16:45:40