我在解决Oracle SQL问题时遇到问题。我必须回到每个部门最近雇用的员工。这需要我使用两个表:DEPARTMENTS和EMPLOYEES。我必须在没有硬编码的情况下解决这个问题,这意味着我不能使用WHERE子句,我必须使用子查询。我必须先按部门名称和员工姓名按升序对表格进行排序。然后最终结果应该类似于:
我认为内部联接可能有效,我的代码就是这样:
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属性。我不断收到一些错误:
不是表达式的组 不是单一的群体功能 太多的价值
如果有人能向我解释如何处理这个问题或者我做错了什么,那就太棒了
答案 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;
直到每个部门的最新日期为止。那么这是子查询进来的地方,以确保每个部门名称的最大日期是最新的吗?