-1

我已经写了以下选择以从工作表中获取以前的不同等级值。这很好用,但是否可以简化没有 3 个级别的代码?

    select value_1 
      from ( select distinct 
                    value_1,
                    date_from,
                    date_to,
                    emp_id,
                    (select o.value_1 
                      from jobs o
                      where o.emp_id=w.emp_id 
                        and (
                              (o.date_to >= sysdate and o.date_from <= sysdate) or
                              (o.data_from <= sysdate and o.data_to is null)
                             )
                      ) current_grade
           from jobs w
          where w.emp_id = t.emp_id 
          order by data_from desc
           )
    where value_1 != current_grade 
      and data_from <= sysdate 
      and rownum=1 
      and t.emp_id=123 
    order by data_from desc, 
             value_1, 
             emp_id

它应该做什么?我想从工作表中选择以前不同的等级值。该表用于存储每个员工的职位,它们有 date_from、date_to,另外在 value_1 中我们存储等级符号。对我来说重要的是选择以前可能改变了 3 个位置的以前不同的等级值。

4

2 回答 2

2

在这种情况下,我认为您无法摆脱三级查询,但可以简化它。正如我在评论中指出的那样,外部查询中的 ORDER BY 是多余的,如果第二个查询中的 ORDER BY 不存在,您实际上会得到不正确的结果。Oracle 的 rownum 不像其他数据库的 Top-N 查询那样工作——rownum 是在order by之前rownum=计算的,因此与 ORDER BY 一起使用不一定会返回最高行。

这应该会产生所需的结果,并且稍微紧凑:

SELECT
    value_1
FROM
(
    SELECT
        value_1
    FROM
        jobs w
    WHERE
        date_from <= sysdate
        and emp_id=123
        and value_1 != (SELECT value_1
                          FROM jobs o
                         WHERE o.emp_id = w.emp_id
                                AND (o.date_to >= sysdate and o.date_from <= sysdate
                                     OR o.date_from <= sysdate and o.date_to is null))
    ORDER BY date_from desc                  
)
WHERE
    rownum = 1

SQLFiddle在这里

于 2013-09-09T12:33:21.273 回答
-1

您可以通过获取过去最新 date_to 值的 value_1 来使用单个表命中。

select value_1 from jobs where date_to < sysdate and emp_id = 123

如果您需要最新的工作角色,请按 desc 订购并获得第一行。

于 2013-09-10T12:56:32.283 回答