我正在尝试执行一个相当复杂的查询,但无法弄清楚如何将其作为单个MySQL查询。 给出3个表
员工,办公室,employee_notes
员工与办公室没有直接联系,因为他们可以定期搬迁办公室。移动时,employee_notes将使用新的办公室ID进行更新。因此,员工备注中的每一行都有office_id,employee_id和切换日期。如果我想获得给定员工的当前办公室ID,我可以这样做:
SELECT en.office_id FROM employee_notes AS en WHERE en.employee_id =
'userid' ORDER BY date DESC LIMIT 1;
但是,如果我有一个办公室,即我有office_id,而且我想让所有员工在指定日期在该办公室工作,我不确定如何进行查询。
我的第一次尝试是这样的:
SELECT emp.* FROM employees AS emp WHERE emp.id = (SELECT en.employee_id FROM employee_notes AS en WHERE en.date < 'somedate' ORDER BY date DESC LIMIT 1);
问题是,在上面的查询中,内部SELECT不会过滤具有给定office id的employee_notes。所以我能做到:
SELECT emp.* FROM employees AS emp WHERE emp.id = (SELECT en.employee_id FROM employee_notes AS en WHERE en.date < 'somedate' AND en.office_id = 'someOfficeId' ORDER BY date DESC LIMIT 1);
然后内部查询仅查看办公室ID为“someOfficeId”的办公室。例如如果员工A在一周之前在某个办公室工作,但后来改为另一个办公室,那么内部查询将无法识别这一点,整个查询会在一些办公室给我雇员A作为雇员。
所以,我的下一个想法是在内部查询之外采用 en.office_id ='someOfficeId'。 e.g。
SELECT emp.* FROM employees AS emp WHERE emp.id = (SELECT en.employee_id FROM employee_notes AS en WHERE en.date < 'somedate' ORDER BY date DESC LIMIT 1) AND en.office_id = 'someOfficeId';
但是,由于我在WHERE子句中引用了别名,因此会出现MySQL错误。 我不确定下一步该尝试什么。
任何帮助表示感谢。
答案 0 :(得分:0)
也许最简单的方法是使用substring_index()
/ group_concat()
技巧来获取最近的办公室:
SELECT en.employee_id,
substring_index(group_concat(office_id order by date desc), ',', 1) as office_id
FROM employee_notes en
WHERE en.date < 'somedate'
GROUP BY en.employee_id
HAVING office_id = 'someoffice';
您也可以使用join
和聚合:
select en.*
from employee_notes en join
(select employee_id, max(date) as maxdate
from employee_notes en2
where date < 'somedate'
group by employee_id
) ed
on en.employee_id = ed.employee_id and en.date = ed.maxdate
where en.office_id = 'someid';
答案 1 :(得分:0)
/* how do you know, however, to which office an employee belongs if he/she had no switch whatsoever? is there an office field in the employees table ? */
SELECT NVL(n.office_id, e.office_id ) officeId, NVL(n.employee_id, e.employee_id) employeeID
FROM
/* gives the last switch per employee (employees not listed here had no switch) */
(SELECT employee_id, date_of_switch
FROM employee_notes n
GROUP BY employee_id, max(date_of_switch)) m,
/* join with employee_notes to get the office of the last switch */
employee_notes n,
employees e
WHERE
/* if employee is not listed in M, he/she had no switch */
e.employee_id = m.employee_id (+)
AND n.switch_date = m.switch_date
AND n.employee_id = m.employee_id
ORDER BY
officeId