sql >> データベース >  >> RDS >> Oracle

Oracle外部結合が期待どおりに機能しない

    あなたが本当に望んでいるのは内部参加であるように思えます。 (+)をドロップして、探しているものが戻ってくるかどうかを確認します。さらに、@ GordonLinoffは、優れた提案を行います。ANSI結合構文の使用に慣れてください。これは、古いスタイルの「すべての条件をWHERE句に入れてから、パズルを解く」スタイルよりも表現力があり、理解しやすいものです。 。

    ANSI標準の結合構文を使用してこのクエリを書き直す方法は次のとおりです。

    SELECT *
      FROM PER_ALL_ASSIGNMENTS_F paaf
      INNER JOIN PAY_ALL_PAYROLLS_F payr
        ON payr.PAYROLL_ID = paaf.PAYROLL_ID
      WHERE SYSDATE BETWEEN paaf.EFFECTIVE_START_DATE
                        AND paaf.EFFECTIVE_END_DATE AND
            paaf.ASSIGNMENT_TYPE IN ('E', 'C') AND
            paaf.PRIMARY_FLAG = 'Y' AND
            payr.ATTRIBUTE1 = 'TINT' AND
            paaf.EFFECTIVE_START_DATE BETWEEN NVL(payr.EFFECTIVE_START_DATE, TO_DATE('01/01/1000', 'DD/MM/YYYY')) 
                                          AND NVL(payr.EFFECTIVE_END_DATE, TO_DATE('31/12/4712', 'DD/MM/YYYY'))
    

    もう1つの小さな問題。問題が発生する可能性のある日付値でBETWEENを使用していることに気付きました。たとえば、PER_ALL_ASSIGNMENTS_Fのある行に2013年1月1日のEFFECTIVE_START_DATEと2013年6月30日のEFFECTIVE_END_DATEがあり、さらに現在の日付と時刻が2013年6月30日であるとします。 07:02:04AMに。これらのデータ値が与えられると、PER_ALL_ASSIGNMENTS_Fのこの行はNOTになります あなたがそれを期待するかもしれませんが、選択されます。問題は、DATE値に入力されたフィールドが日、月、年のみの場合、時、分、秒はデフォルトでゼロになることです。したがって、終了日は本当に 2013年6月30日の00:00:00は、2013年6月30日の午前07:02:04の現在の日付/時刻より前であるため、日付の比較により行が無視されます。 EFFECTIVE_END_DATEフィールドがデータベースにどのように入力されているかわかりません-うまくいけば、完全に入力されています。 30-JUN-2013 23:59:59-しかし、そうでない場合は、日付の比較を次のようにする必要があるかもしれません

    TRUNC(SYSDATE) BETWEEN paaf.EFFECTIVE_START_DATE
                       AND paaf.EFFECTIVE_END_DATE
    

    または

    SYSDATE BETWEEN paaf.EFFECTIVE_START_DATE
                AND paaf.EFFECTIVE_END_DATE + INTERVAL '1' DAY - INTERVAL '1' SECOND
    

    (後者の形式では、(EFFECTIVE_START_DATE、EFFECTIVE_END_DATE)に存在する可能性のある非関数ベースのインデックスを使用できなくなるため、前者の方がおそらく適切です。

    共有してお楽しみください。



    1. MYSQLは、切り替えられた場合でも2つの列のエントリを区別します

    2. GrailsアプリのMySqlで壊れたパイプの例外

    3. MySQLクロステーブルカウント(*)クエリヘルプ

    4. mysqlの同じテーブルの行を比較します