ORACLE SQL:返回最近雇用的员工

时间:2016-07-24 18:56:57

标签: sql oracle subquery inner-join

我在解决Oracle SQL问题时遇到问题。我必须回到每个部门最近雇用的员工。这需要我使用两个表:DEPARTMENTS和EMPLOYEES。我必须在没有硬编码的情况下解决这个问题,这意味着我不能使用WHERE子句,我必须使用子查询。我必须先按部门名称和员工姓名按升序对表格进行排序。然后最终结果应该类似于:

enter image description here

我认为内部联接可能有效,我的代码就是这样:

     SELECT d1.DEPARTMENT_ID , d1.DEPARTMENT_NAME, 
     e1.EMPLOYEES_ID,e1.EMPLOYEES_NAME, e1.JOB_TITLE, e1.JOB_TITLE
     FROM DEPARTMENTS d1
     INNER JOIN EMPLOYEES e1
     ON d1.DEPARTMENT_ID = e1.DEPARTMENT_ID
     HAVING MAX(e1.HIRE_DATE) = (SELECT e1.HIRE_DATE
                        FROM EMPLOYEES
                        GROUP BY d1.DEPARTMENT_ID)
     ORDER BY d1.DEPARTMENT_NAME, e1.EMPLOYEES_NAME ASC;

DEPARTMENTS和EMPLOYEES共享DEPARTMENT_ID属性,所以我将它们链接到那里,但我不确定如何在最终结果中获取e1属性。我不断收到一些错误:

不是表达式的组 不是单一的群体功能 太多的价值

如果有人能向我解释如何处理这个问题或者我做错了什么,那就太棒了

4 个答案:

答案 0 :(得分:0)

- 你也可以使用rownumber

select *
from
(
SELECT d1.DEPARTMENT_ID , d1.DEPARTMENT_NAME, 
         e1.EMPLOYEES_ID,e1.EMPLOYEES_NAME, e1.JOB_TITLE, e1.JOB_TITLE,
Row_number() over (partition by d1.DEPARTMENT_ID order by hiredate desc) as rn
         FROM DEPARTMENTS d1
         INNER JOIN EMPLOYEES e1
         ON d1.DEPARTMENT_ID = e1.DEPARTMENT_ID
)
where rn=1

答案 1 :(得分:0)

@TheGameiswar给你很好的答案(使用Row_number!),这里基于他的答案,但没有WHERE,这里使用子查询:

with dep(id,name) as (select 1, 'sales' from dual union all 
                      select 2, 'develop' from dual),
     emp(id,dep_id, name, hire_date) as (select 1,1,'john',sysdate from dual union all 
                                         select 2,1,'kim', sysdate-100 from dual union all
                                         select 3,1,'kim', sysdate-101 from dual union all
                                         select 4,2,'kate', sysdate-1000 from dual union all
                                         select 5,2,'richard', sysdate-300 from dual union all
                                         select 6,2,'jack', sysdate-500 from dual)

select dep.*, emp.*
  from dep inner join 
         (select emp.*, row_number() over (partition by emp.dep_id order by hire_date desc) rn from emp) emp 
    on dep.id = emp.dep_id
    -- here no WHERE clause :)
    and emp.rn = 1

order by dep.name,emp.name

输出:

        ID NAME            ID     DEP_ID NAME    HIRE_DATE         RN
---------- ------- ---------- ---------- ------- --------- ----------
         2 develop          5          2 richard 29.09.15           1
         1 sales            1          1 john    25.07.16           1

或者您可以像这样使用双group by

with dep(id,name) as (select 1, 'sales' from dual union all 
                      select 2, 'develop' from dual),
     emp(id,dep_id, name, hire_date) as (select 1,1,'john',sysdate from dual union all 
                                         select 2,1,'kim', sysdate-100 from dual union all
                                         select 3,1,'kim', sysdate-101 from dual union all
                                         select 4,2,'kate', sysdate-1000 from dual union all
                                         select 5,2,'richard', to_date('1.07.2016','dd.mm.yyyy') from dual union all
                                         select 6,2,'richard2', to_date('1.07.2016','dd.mm.yyyy') from dual union all
                                         select 7,2,'jack', sysdate-500 from dual)

select * from dep inner join emp on dep.id = emp.dep_id
                  inner join 
              (select max(emp.id) emp_id from emp 
                      inner join (select max(hire_date) hdate from emp group by dep_id) emp_max
                         on emp.hire_date = emp_max.hdate 
                group by hdate) last_hire_emp 
  on emp.id = last_hire_emp.emp_id
order by dep.name,emp.name  

输出:

        ID NAME            ID     DEP_ID NAME     HIRE_DATE     EMP_ID
---------- ------- ---------- ---------- -------- --------- ----------
         2 develop          6          2 richard2 01.07.16           6
         1 sales            1          1 john     25.07.16           1

最后一个例子在hire_date上有2个emp,在这个例子中我用max(id)获取

答案 2 :(得分:0)

内部联接到按部门选择max(hiredate)的子查询。

首先,选择最长雇用日期和按部门分组。

Select department_id, max(hiredate) hiredate
from employees
group by department_id

现在我们将其用作子查询,并将其连接到其余员工数据。此处的内连接用作过滤器(或where子句)

select (pick your fields)
from
  (Select department_id, max(hiredate) hiredate
   from enmployees
   group by department_id) maxhire
inner join  DEPARTMENTS d1
  on d1.department_id = maxhire.department_id
INNER JOIN EMPLOYEES e1
  ON d1.DEPARTMENT_ID = e1.DEPARTMENT_ID
  and maxhire.hiredate = e1.hiredate

如果在最近的雇佣人员中雇佣了多名人员,此方法将返回多个结果。

答案 3 :(得分:0)

所以我做了更多的计算并想出了这个:

    set linesize 200
    SELECT DEPARTMENTS.DEPARTMENT_ID AS 
    "DEPARTMENT ID",DEPARTMENTS.DEPARTMENT_NAME AS "DEPARTMENT NAME", 
    EMPLOYEES_ID AS "EMPLOYEE ID", 
    EMPLOYEES_NAME AS "EMPLOYEE NAME", MAX(HIRE_DATE) AS "HIRE DATE"

    FROM EMPLOYEES

    INNER JOIN DEPARTMENTS

    ON DEPARTMENTS.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID 

    GROUP BY DEPARTMENTS.DEPARTMENT_ID, 
    DEPARTMENTS.DEPARTMENT_NAME, EMPLOYEES_ID, EMPLOYEES_NAME

    ORDER BY DEPARTMENTS.DEPARTMENT_NAME;

直到每个部门的最新日期为止。那么这是子查询进来的地方,以确保每个部门名称的最大日期是最新的吗?