SQL查询员工数据库

时间:2016-08-20 11:44:42

标签: sql oracle

我想找到支付 最低总薪资 的公司以及支付的总薪水。

详情如下,

works( empid, companyname, salary )

我的查询看起来像,

SELECT COMPANYNAME 
FROM WORKS 
WHERE SALARY=
  (SELECT MIN(SUM(SALARY)) 
  FROM 
      (SELECT SUM(SALARY) 
      FROM WORKS 
      GROUP BY COMPANYNAME) 
GROUP BY COMPANYNAME);

但这并不会返回任何行。

我是SQL的新手,所以我希望你能以一种易于理解的方式回复我。

2 个答案:

答案 0 :(得分:2)

您的查询没有返回任何行,因为您正在查找原始表works中的行。在该表中,您没有为任何公司支付工资,只有个人员工工资,因此查询当然不会返回任何行。没有任何员工的薪水等于公司中的最低工资总额。

有很多方法可以解决这个问题,但由于你是初学者,你应该只寻找使用基本SQL语句的解决方案(即使你不会在生产中使用这样的解决方案)。您现在的目标是了解SQL的工作原理,而不是获得最快或最先进的解决方案。

有了这样的说法:首先,您需要创建一个按公司对行进行分组的查询,然后选择公司(或公司,如果首先存在并列关系),总薪水最低。为此,您需要使用GROUP BY,就像您已经使用的那样。然后,要从GROUPS(而不是原始行)中进行选择,您需要使用HAVING子句,而不是WHERE子句。像这样:

select   companyname, sum(salary) as total_salary
from     works
group by companyname 
having   sum(salary) = ( select   min(sum(salary))
                         from     works
                         group by companyname
                       )
;

另请注意,SQL允许您将聚合函数包装在另一个函数中 - 您可以直接针对原始表编写select min(sum(salary))。这在我的子查询中有说明;与你原来的尝试相比。

答案 1 :(得分:1)

以下是Oracle 12c +中的一种方法:

SELECT COMPANYNAME, SUM(SALARY) 
FROM WORKS 
GROUP BY COMPANYNAME
ORDER BY SUM(SALARY)
FETCH FIRST 1 ROW ONLY;

在旧版本中,请使用ROW_NUMBER()RANK()DENSE_RANK()。所以,如果可能存在联系,那么使用:

SELECT w.*
FROM (SELECT COMPANYNAME, SUM(SALARY) as total_salary,
             RANK() OVER (ORDER BY SUM(SALARY)) as seqnum
      FROM WORKS 
      GROUP BY COMPANYNAME
     ) w
WHERE seqnum = 1;

这会在关系的情况下返回重复项。如果要保证始终只返回一行,则可以使用ROW_NUMBER()