我想找到支付 最低总薪资 的公司以及支付的总薪水。
详情如下,
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的新手,所以我希望你能以一种易于理解的方式回复我。
答案 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()
。