如何简化这个oracle sql查询?

时间:2013-09-09 10:41:54

标签: sql oracle select

我写了以下select来从jobs表中获取以前的不同成绩值。 这很好用但是可以简化它没有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个职位的不同等级值。

2 个答案:

答案 0 :(得分:2)

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

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

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 here

答案 1 :(得分:-1)

您可以通过获取过去的最新date_to值的value_1来执行单个表格。

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

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