我尝试在线解决有2个表的SQL问题,
员工表
Employee表包含所有员工。
+----+-------+--------+--------------+
| Id | Name | Sa1ary | DepartmentId |
+----+-------+--------+--------------+
| 1 | Joe | 70000 | 1 |
| 2 | Henry | 80000 | 2 |
| 3 | Sam | 60000 | 2 |
| 4 | Max | 90000 | 1 |
| 5 | Janet | 69000 | 1 |
| 6 | Randy | 85000 | 1 |
+----+-------+--------+--------------+
部门表
SQL应该返回以下数据
我有以下SQL查询,
SELECT D.Name AS Department, E.Name AS Employee, E.Salary AS Salary
FROM Employee E INNER JOIN Department D ON E.DepartmentId = D.Id
WHERE (SELECT COUNT(DISTINCT(Salary)) FROM Employee
WHERE DepartmentId = E.DepartmentId AND Salary > E.Salary) < 3
ORDER by E.DepartmentId, E.Salary DESC;
SQL很好,但是,我对< 3
部分感到困惑。不应该是关于前3名工资问题的问题= 3吗?我很感激SQL的解释,并会有所帮助。
答案 0 :(得分:5)
如果您添加了一列Count employees who earn more
,那么您的表格将如下所示
+----+-------+--------+--------------+-------------------------------+
| Id | Name | Sa1ary | DepartmentId | Count employees who earn more |
+----+-------+--------+--------------+-------------------------------+
| 1 | Joe | 70000 | 1 | 2 |
| 2 | Henry | 80000 | 2 | 0 |
| 3 | Sam | 60000 | 2 | 1 |
| 4 | Max | 90000 | 1 | 0 |
| 5 | Janet | 69000 | 1 | 3 |
| 6 | Randy | 85000 | 1 | 1 |
+----+-------+--------+--------------+-------------------------------+
然后找到每个部门的前3名。你的WHERE将是
WHERE `Count employees who earn more` < 3
如果你有=3
,它将返回唯一的第四位
由于你没有那个列,这就是这个SQL的作用
(SELECT COUNT(DISTINCT(Salary)) FROM Employee
WHERE DepartmentId = E.DepartmentId AND Salary > E.Salary)
如果您想制作上述表格,可以执行以下操作
SELECT
D.Name AS Department,
E.Name AS Employee,
E.Salary AS Salary,
Count(E2.Salary) as Count_employees_who_earn_more
FROM Employee E
INNER JOIN Department D
ON E.DepartmentId = D.Id
LEFT JOIN Employee E2 ON
e2.DepartmentId = E.DepartmentId
AND E2.Salary > E.Salary
GROUP BY D.Name ,
E.Name ,
E.Salary
答案 1 :(得分:0)
我正在处理同样的SQL问题。
以防有人可能需要帮助。
这是我想出的答案。
SELECT
dpt.Name AS Department,
e1.Name AS Employee,
e1.Salary AS Salary
FROM Employee AS e1
INNER JOIN Department dpt
ON e1.DepartmentID = dpt.Id
WHERE 3 > (
SELECT COUNT(DISTINCT Salary)
FROM Employee AS e2
WHERE e2.Salary > e1.Salary
AND e1.DepartmentID = e2.DepartmentID
)
ORDER BY
Department ASC,
Salary DESC;
困难的部分是获得每个部门的前3名工资。 我首先计算 [薪水较高的员工人数] 。
之后,我使用 3&gt; [薪水较高的员工人数] 仅保留前3名薪水。 (如果前三名中有超过3名员工,也就是说其中一些员工的薪水相同,则所有员工都将被包括在内。)
查询
SELECT *
FROM Employee e1
WHERE 3 > (
SELECT COUNT(DISTINCT Salary)
FROM Employee e2
WHERE e2.Salary > e1.Salary
AND e1.DepartmentID = e2.DepartmentID
);
输出
+------+-------+--------+--------------+
| Id | Name | Salary | DepartmentId |
+------+-------+--------+--------------+
| 1 | Joe | 70000 | 1 |
| 2 | Henry | 80000 | 2 |
| 3 | Sam | 60000 | 2 |
| 4 | Max | 90000 | 1 |
| 6 | Randy | 85000 | 1 |
+------+-------+--------+--------------+
然后这是容易的部分。您可以将此表与DepartmentID上的Department一起加入以获取部门名称。
最终输出
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT | Max | 90000 |
| IT | Randy | 85000 |
| IT | Joe | 70000 |
| Sales | Henry | 80000 |
| Sales | Sam | 60000 |
+------------+----------+--------+
答案 2 :(得分:0)
with sal_CTE as
(
select e.Id as emp_id,
d.Name as dept_name,
e.Name as emp_name,
e.Salary as emp_sal,
DENSE_RANK() OVER(PARTITION BY d.ID Order By e.Salary desc) as rank
from Employee e inner join department d
ON (e.DepartmentId = d.Id)
)
select dept_name as Department,
emp_name as Employee,
emp_sal as Salary from sal_CTE
where rank <=3
order by dept_name;
答案 3 :(得分:0)
您可以通过在mysql> 5.7和所有支持窗口功能的主要数据库中使用窗口功能来实现此目的
select dept_name, emp_name, salary from (
select d.name as dept_name, e.name as emp_name, e.salary,
rank() over(partition by d.name order by e.salary desc) as rank_count
from employee e, department d
where d.id = e.dept_id) a where a.rank_count <4
如果一个表具有空键而另一个表没有映射键,则可以根据需要将内部联接更改为左联接
答案 4 :(得分:0)
WITH table1 AS
(
SELECT Department.Name AS Department, Employee.Name AS Employee, Salary
FROM Employee
INNER JOIN Department
ON DepartmentId = Department.Id
),
table2 AS
(
SELECT * FROM (
SELECT Department, Employee, Salary, DENSE_RANK() OVER (PARTITION BY Department ORDER BY Salary DESC) AS rank
FROM table1
) t
WHERE rank<=3
)
SELECT Department, Employee, Salary
FROM table2;
答案 5 :(得分:0)
SELECT
Department,
Employee,
Salary
FROM
(
SELECT
D.Name AS Department,
E.Name AS Employee,
E.Salary AS Salary,
DENSE_RANK() OVER (
PARTITION BY d.NAME
ORDER BY d.name, E.SALARY DESC
) AS RANK
FROM Employee E
INNER JOIN Department D
ON E.DepartmentId = D.Id
group by d.name, e.name, e.salary
)
WHERE RANK <= 3
对于Oracle 11G
答案 6 :(得分:0)
dense_rank()
works,rank()
会在 2 rows
与 same salary
之间产生间隙。
with temp_tbl as (
select d.name as Department,i.name as Employee,Salary,dense_rank() over (partition by departmentid order by salary desc) as rnk
from employee i,department d
where i.departmentid=d.id)
select Department,Employee,Salary
from temp_tbl
where rnk<4
答案 7 :(得分:-1)
With CTE_EMP AS
(
Select d.Name AS Department, e.Name as Employee, e.Salary,
ROW_NUMBER() over (partition by DepartmentId order by Salary desc) AS RowNumber
From Employee e
JOIN Department d on d.Id = e.DepartmentId
)
Select Department, Employee, Salary FROM CTE_EMP Where RowNumber <= 3