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

日付の比較で異常な結果が返される-SQLOracle

    適切なで完璧に機能します TO_DATEの使用 およびDATE値。

    • TO_DATEは絶対に使用しないでください 日付暗黙的に文字列に変換してから、ロケール固有のNLS形式を使用して日付に戻します

    • '2015年1月1日' は日付ではなく、文字列です。 TO_DATEを使用する必要があります 明示的に日付に変換します。

    何が起こるか見てみましょう:

    SQL> explain plan for select * from dual where to_date(sysdate) > to_date(sysdate -1);
    
    Explained.
    
    SQL> select * from table(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    Plan hash value: 3752461848
    
    ---------------------------------------------------------------------------
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |     1 |     2 |     2   (0)| 00:00:01 |
    |*  1 |  FILTER            |      |       |       |            |          |
    |   2 |   TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |
    ---------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    ---------------------------------------------------
    
       1 - filter(TO_DATE(TO_CHAR([email protected]!))>TO_DATE(TO_CHAR([email protected]!-1)))
    
    14 rows selected.
    
    SQL>
    

    したがって、適用される実際のフィルターは filter(TO_DATE(TO_CHAR( [email protected] !)) ロケール固有のNLS形式に基づく暗黙的な変換が原因で、誤った出力が表示されます。

    とにかく、元の質問に戻ります。

    たとえば、

    データが次のようになっているとしましょう:

    セットアップ:

    SQL> CREATE TABLE t
      2      (week_no VARCHAR2(2), long_week_no VARCHAR2(2), week_start_date DATE, week_end_date DATE, mnth VARCHAR2(3), yr VARCHAR2(4))
      3  ;
    
    Table created.
    
    SQL>
    SQL>
    SQL> INSERT ALL
      2      INTO t (week_no, long_week_no, week_start_date, week_end_date, mnth, yr)
      3           VALUES ('1', '1A', TO_DATE('01/01/2015','DD/MM/YYYY'), TO_DATE('03/01/2015','DD/MM/YYYY'), 'JAN', '2015')
      4      INTO t (week_no, long_week_no, week_start_date, week_end_date, mnth, yr)
      5           VALUES ('1', '1B', TO_DATE('04/01/2015','DD/MM/YYYY'), TO_DATE('10/01/2015','DD/MM/YYYY'), 'JAN', '2015')
      6      INTO t (week_no, long_week_no, week_start_date, week_end_date, mnth, yr)
      7           VALUES ('2', '2', TO_DATE('11/01/2015','DD/MM/YYYY'), TO_DATE('17/01/2015','DD/MM/YYYY'), 'JAN', '2015')
      8      INTO t (week_no, long_week_no, week_start_date, week_end_date, mnth, yr)
      9           VALUES ('3', '3', TO_DATE('18/01/2015','DD/MM/YYYY'), TO_DATE('24/01/2015','DD/MM/YYYY'), 'JAN', '2015')
     10      INTO t (week_no, long_week_no, week_start_date, week_end_date, mnth, yr)
     11           VALUES ('51', '51', TO_DATE('20/12/2014','DD/MM/YYYY'), TO_DATE('26/12/2015','DD/MM/YYYY'), 'DEC', '2014')
     12  SELECT * FROM dual
     13  ;
    
    5 rows created.
    
    SQL>
    SQL> COMMIT;
    
    Commit complete.
    
    SQL>
    

    表:

    SQL> SELECT * FROM t;
    
    WE LO WEEK_STAR WEEK_END_ MNT YR
    -- -- --------- --------- --- ----
    1  1A 01-JAN-15 03-JAN-15 JAN 2015
    1  1B 04-JAN-15 10-JAN-15 JAN 2015
    2  2  11-JAN-15 17-JAN-15 JAN 2015
    3  3  18-JAN-15 24-JAN-15 JAN 2015
    51 51 20-DEC-14 26-DEC-15 DEC 2014
    
    SQL>
    

    日付範囲に基づいて行をフィルタリングするクエリ:

    SQL> SELECT *
      2  FROM   t
      3  WHERE  To_date('15/01/2015', 'DD/MM/YYYY') BETWEEN
      4         week_start_date AND
      5         week_end_date;
    
    WE LO WEEK_STAR WEEK_END_ MNT YR
    -- -- --------- --------- --- ----
    2  2  11-JAN-15 17-JAN-15 JAN 2015
    51 51 20-DEC-14 26-DEC-15 DEC 2014
    
    SQL>
    



    1. 製品属性のデータベーススキーマ

    2. 文字列リテラルが長すぎます-Oracle11gr2で長いxmlデータをclobデータ型に割り当てる方法

    3. Oracleを使用してテーブル内のXML空タグのダミー値を取得するにはどうすればよいですか?

    4. Oracleプロシージャでテーブルを切り捨てる方法は?