我有一张表格,显示员工的部门和职位以及职位的最后更新。我的目标是列出每个部门中每个部门的最新职位(每个部门的MAX last_update)。但问题是我无法连接两个列并通过此连接将它们分组。
例如,表格是
Departement Position employee last_update
dep1 pos1 employee1 16:00
dep1 pos2 employee1 08:00
dep1 pos3 employee1 11:00
dep2 pos4 employee2 13:00
dep2 pos5 employee2 09:00
dep2 pos6 employee3 07:00
期望的结果应该是:
Departement Position employee last_update
dep1 pos1 employee1 16:00
dep2 pos4 employee2 13:00
dep2 pos6 employee3 07:00
我必须连接员工和他的部门,并按部门和员工的姓名对他们进行分组以获得结果。 但是我不能用oracle这样的小组进行连接:
SELECT t.department, t.position,concat(t.department,t.employee), t.employee , r.MaxTime
FROM (SELECT department,position,employee, MAX(last_update) as MaxTime
FROM employeetable
GROUP BY (concat(department,employee))) r
INNER JOIN employeetable t ON t.departement = r.department AND t.last_update = r.MaxTime
非常感谢
答案 0 :(得分:1)
为什么要尝试按两列的串联进行分组而不仅仅是两列本身?另外,last_update
列的数据类型是什么?我真诚地希望它是DATE
或TIMESTAMP
。话虽如此,您正在尝试做什么 - 找到每个部门和员工的最新行?如果是这样,那么就像:
with sample_data as (select 'dep1' department, 'pos1' position, 'employee1' employee, to_date('19/02/2015 16:00', 'dd/mm/yyyy hh24:mi:ss') last_update from dual union all
select 'dep1' department, 'pos2' position, 'employee1' employee, to_date('19/02/2015 08:00', 'dd/mm/yyyy hh24:mi:ss') last_update from dual union all
select 'dep1' department, 'pos3' position, 'employee1' employee, to_date('19/02/2015 11:00', 'dd/mm/yyyy hh24:mi:ss') last_update from dual union all
select 'dep2' department, 'pos4' position, 'employee2' employee, to_date('19/02/2015 13:00', 'dd/mm/yyyy hh24:mi:ss') last_update from dual union all
select 'dep2' department, 'pos5' position, 'employee2' employee, to_date('19/02/2015 09:00', 'dd/mm/yyyy hh24:mi:ss') last_update from dual union all
select 'dep2' department, 'pos6' position, 'employee3' employee, to_date('19/02/2015 07:00', 'dd/mm/yyyy hh24:mi:ss') last_update from dual)
select department, position, employee, last_update
from (select sd.*,
row_number() over (partition by department, employee order by last_update desc) rn
from sample_data sd)
where rn = 1;
DEPARTMENT POSITION EMPLOYEE LAST_UPDATE
---------- -------- --------- ---------------------
dep1 pos1 employee1 19/02/2015 16:00:00
dep2 pos4 employee2 19/02/2015 13:00:00
dep2 pos6 employee3 19/02/2015 07:00:00
答案 1 :(得分:1)
您可以按子查询中的单独部门和员工列进行分组,并且您不希望在其中包含该职位;然后在两个列的外部查询连接中:
SELECT t.department, t.position, t.employee,
to_char(r.MaxTime, 'HH24:MI') as MaxTime
FROM (SELECT department, employee, MAX(last_update) as MaxTime
FROM employeetable
GROUP BY department, employee) r
INNER JOIN employeetable t ON t.department = r.department
AND t.employee = r.employee
AND t.last_update = r.MaxTime;
DEPARTMENT POSITION EMPLOYEE MAXTIME
---------- -------- ---------- -------
dep1 pos1 employee1 16:00
dep2 pos4 employee2 13:00
dep2 pos6 employee3 07:00
您还可以在子查询中使用分析排名函数来避免自联接:
SELECT department, position, employee,
to_char(last_update, 'HH24:MI') as maxtime
FROM (
SELECT department, position, employee, last_update,
rank() over (partition by department, employee
order by last_update desc) as rnk
FROM employeetable
)
WHERE rnk = 1;
或使用max keep first dense_rank
:
SELECT department,
max(position) keep (dense_rank first order by last_update desc) as position,
employee,
to_char(max(last_update)
keep (dense_rank first order by last_update desc), 'HH24:MI') as maxtime
FROM employeetable
GROUP BY department, employee;
我假设您的last_update
列确实是一个约会,而您只是为了简洁而展示时间;否则你需要转换价值,并且你无法在不同的日子里对时间进行排名......
SQL Fiddle采用这三种方法。
答案 2 :(得分:0)
保持简单:
SELECT department, position, employee, last_update
FROM
(
SELECT department, position, employee, last_update
, ROW_NUMBER() OVER (PARTITION BY employee, department ORDER BY department, employee, last_update DESC) rseq
FROM
(
select 'dep1' department, 'pos1' position, 'employee1' employee, to_char(to_date('19/02/2015 16:00', 'dd/mm/yyyy hh24:mi:ss'), 'mm-dd-yyyy hh24:mi:ss') last_update from dual union all
select 'dep1' department, 'pos2' position, 'employee1' employee, to_char(to_date('19/02/2015 08:00', 'dd/mm/yyyy hh24:mi:ss'), 'mm-dd-yyyy hh24:mi:ss') last_update from dual union all
select 'dep1' department, 'pos3' position, 'employee1' employee, to_char(to_date('19/02/2015 11:00', 'dd/mm/yyyy hh24:mi:ss'), 'mm-dd-yyyy hh24:mi:ss') last_update from dual union all
select 'dep2' department, 'pos4' position, 'employee2' employee, to_char(to_date('19/02/2015 13:00', 'dd/mm/yyyy hh24:mi:ss'), 'mm-dd-yyyy hh24:mi:ss') last_update from dual union all
select 'dep2' department, 'pos5' position, 'employee2' employee, to_char(to_date('19/02/2015 09:00', 'dd/mm/yyyy hh24:mi:ss'), 'mm-dd-yyyy hh24:mi:ss') last_update from dual union all
select 'dep2' department, 'pos6' position, 'employee3' employee, to_char(to_date('19/02/2015 07:00', 'dd/mm/yyyy hh24:mi:ss'), 'mm-dd-yyyy hh24:mi:ss') last_update from dual
)
)
WHERE rseq = 1
/
dep1 pos1 employee1 02-19-2015 16:00:00
dep2 pos4 employee2 02-19-2015 13:00:00
dep2 pos6 employee3 02-19-2015 07:00:00
答案 3 :(得分:0)
怎么样:
SELECT t.department, t.position, t.employee , t.last_update
From employeetable t
Where not exists (
SELECT 'x'
From employeetable t2
Where t2.employee=t.employee
and t2.last_update > t.last_update
)