-1

ジョブテーブルから以前の異なるグレード値を取得するために、次のselectを作成しました。これはうまくいきますが、コードを単純化して 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

この場合、3 レベルのクエリから逃れることはできないと思いますが、単純化することはできます。コメントで指摘したように、外側のクエリの ORDER BY は不要であり、2 番目のクエリに ORDER BY がないと、実際には間違った結果が得られます。Oracle の rownum は、他のデータベースの Top-N クエリのようには機能しません。rownum はorder by の前に計算されるため、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

于 2013-09-09T12:33:21.273 に答える