我正在尝试编写一个SQL请求来计算每年雇佣/解雇的员工数量。
我可以通过此选择获得每个员工的日期:
SELECT HiredDate, FiredDate FROM Employees;
我可以使用此选项列出每年:
SELECT to_char(e1.HiredDate, 'YYYY') Year FROM Employees e1
UNION
SELECT to_char(e2.FiredDate, 'YYYY') Year FROM Employees e2;
但我无法计算每年雇佣/解雇的人数。
修改
员工样本数据:
Name | HiredDate | FiredDate
--------------------------------
John | 01/02/2003 | 03/04/2013
Jack | 05/06/2006 | 07/08/2013
Jean | 03/04/2006 | null
James | 01/02/2013 | null
预期结果:
Year | HiredNumber | FiredNumber
---------------------------------
2003 | 1 | 0
2006 | 2 | 0
2013 | 1 | 2
答案 0 :(得分:1)
可能有几年没有招聘,多年没有解雇。因此,解决此问题的最简单方法是使用两个子查询,每个子查询一个,并使用完全外连接将它们连接起来。
with e1 as (
select extract(year from hireddate) as emp_year
, count(hireddate) as hired_count
from employees
where hireddate is not null
group by extract(year from hireddate)
)
, e2 as (
select extract(year from fireddate) as emp_year
, count(fireddate) as fired_count
from employees
where fireddate is not null
group by extract(year from fireddate)
)
select coalesce (e1.emp_year, e2.emp_year) as emp_year
, nvl(e1.hired_count, 0) as hired_count
, nvl(e2.fired_count, 0) as fired_count
from e1
full outer join e2
on e1.emp_year = e2.emp_year
order by 1
备注强>
hireddate
是强制性的,但保留非空检查以保持对称性:)“。它在SQL Developer中运行良好,但不能设置为Visual数据源”
这是一个没有FULL OUTER JOIN的变种:
select emp_year
, sum(hired_count) as hired_count
, sum(fired_count) as fired_count
from (
select extract(year from hireddate) as emp_year
, count(hireddate) as hired_count
, 0 as fired_count
from employees
where hireddate is not null
group by extract(year from hireddate)
union all
select extract(year from fireddate) as emp_year
, 0 as hired_count
, count(fireddate) as fired_count
from employees
where fireddate is not null
group by extract(year from fireddate)
)
group by emp_year
order by 1
答案 1 :(得分:0)
SELECT 'Hired' What, to_char(e1.HiredDate, 'YYYY') Year, COUNT(*) TheCount
FROM Employees e1
GROUP BY to_char(e1.HiredDate, 'YYYY')
UNION ALL
SELECT 'Fired' What, to_char(e2.FiredDate, 'YYYY') Year, COUNT(*) TheCount
FROM Employees e2
GROUP BY to_char(e2.FiredDate, 'YYYY');