【问题标题】:How to write a query to get the latest employee record given the effective date in oracle?给定oracle中的生效日期,如何编写查询以获取最新的员工记录?
【发布时间】:2012-05-21 12:52:55
【问题描述】:

我有一个employee 和employee_history 表。对于employee 表的每次更新,我都会在employee_history 表中插入一条记录。

两个表都有一个名为“生效日期”的列,表示员工在该生效日期的状态。

下面是我的两张桌子。

我需要获取截至该生效日期的最新员工记录。

例如,如果我需要在 5 月 16 日获取员工,我应该从历史表中获取 emp_hist_id = 2 记录。在 6 月 5 日,我应该从 hist 表中获取 emp_hist_id = 4 。

在 8 月 15 日,我应该从员工表本身获取记录。

请帮忙。

【问题讨论】:

  • 为什么不将当前员工记录也存储在employee_history 中呢?那么您只需要查询employee_history 即可获取任何日期的数据。

标签: sql oracle


【解决方案1】:

你可以试试

SELECT * FROM (
  SELECT * FROM (
    (SELECT emp_id, name, email, title, region, division, "effective date" 
     FROM employee
     WHERE emp_id = desired_id)
    UNION
    (SELECT emp_id, name, email, title, region, division, "effective date" 
     FROM employee _history
     WHERE emp_id = desired_id)
  ) t
  WHERE t."effective date" <= desired_date
  ORDER by t."effective date" DESC) p
WHERE ROWNUM = 1

这个想法是从两个表中获取与所需用户相关的记录,然后获取低于所需日期的日期,最后捕获第一个

【讨论】:

  • 我认为您需要将[ ] 替换为" " (假设列名是"effective date" 而不是effective_date
  • @Marco。感谢你的回答。如果我需要所有员工的名单,而不仅仅是一名员工,他们的状态为生效日期怎么办?
  • @Ashish 根据他的查询,如果您删除“WHERE ROWNUM = 1”,它将显示所有行,从而为您提供所有员工。我不是肯定的,但请测试一下。
  • @Tony318。我尝试删除“WHERE ROWNUM = 1”,然后它为员工提供了多个条目。我认为我们需要按生效日期 desc 按员工 ID 顺序分组,然后从每个组中取第一行。
  • @Ashish 尝试按照您所说的去做,如果这不起作用,对 emp_id 执行 SELECT DISTINCT 应​​该将结果缩小到每位员工 1 个条目,但仍允许显示多个员工。
【解决方案2】:

您可以在没有分析函数的情况下解决此问题。这里的子查询计算员工生效日期之前历史记录中最近的生效日期:

select e.*
from employee_history eh join
     (select e.employee_id, max(eh.effective_date) as latest_effective_date
      from employee e join
           employee_history eh
           on e.employee_id = eh.employee_id and
              e.effective_date >= eh.effective_date
     ) ehl
     on eh.employee_id = ehl.employee_id and
        eh.effective_date = ehl.effective_date

此解决方案假定历史记录表中没有重复的生效日期。如果有,那么您还有另一个选择。假设employee_history_ids 是按顺序分配的,取该id 的最大值而不是日期。

使用 Oracle 的分析函数可以使用其他解决方案。

【讨论】:

    【解决方案3】:

    尝试以下方法:

    SELECT *
    FROM
      (SELECT e.emp_id,
              e.name,
              e.email,
              e.title,
              e.region,
              e.division,
              e.effective_date,
              row_number() over (partition BY e.emp_id
                                 ORDER BY e.effective_date DESC) rn
       FROM employee e
       UNION ALL 
       SELECT eh.emp_id,
              eh.name,
              eh.email,
              eh.title,
              eh.region,
              eh.division,
              eh.effective_date,
              row_number() over (partition BY eh.emp_id
                                 ORDER BY eh.effective_date DESC) rn
       FROM employee_history eh)
    WHERE effective_date < to_date('15/06/2012','DD/MM/YYYY')
      AND rn = 1
    

    你可以看到一个更好的例子here

    【讨论】:

      猜你喜欢
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 2023-01-22
      • 2017-10-02
      相关资源
      最近更新 更多