【问题标题】:SQL query to get last dated itemSQL查询以获取最后日期的项目
【发布时间】:2015-03-01 13:46:08
【问题描述】:

我正在尝试执行一个相当复杂的查询,但无法弄清楚如何将其作为单个 MySQL 查询来执行。 给定3张桌子

员工、办公室、员工笔记

员工与办公室没有直接联系,因为他们可以定期搬迁。当他们搬家时,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 没有过滤具有给定办公室 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 一周前在 someOffice' 工作,但后来换到另一个办公室,内部查询将无法识别这一点,整个查询将给我员工 A 作为 someOffice 的员工。

所以,我的下一个想法是将 en.office_id = 'someOfficeId' 置于内部查询之外。 例如

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

但是,这会导致 MySQL 错误,因为我在 WHERE 子句中引用了 en 别名。 我不确定接下来要尝试什么。

任何帮助表示赞赏。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    也许最简单的方法是使用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';
    

    【讨论】:

    • 嗯...这给了我employee_notes,而不是员工
    • @Caveman 。 . .它为您提供employee_idoffice_id。您可以加入所需的适当参考表。我注意到这与您在问题中的示例一致。
    • 是的,你是对的。我与员工进行了第二个示例的内部连接,它似乎有效。谢谢。
    【解决方案2】:

    似乎 Gordon 尝试了一个更优雅/复杂的解决方案。 我试图坚持基础......希望你能说我取得了一些成功。

    /* 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-03
      • 1970-01-01
      • 2016-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多