每年撰写一份雇佣/解雇人数的请求

时间:2017-03-30 07:27:50

标签: sql oracle

我正在尝试编写一个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

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