Date comparison returns unusual result - SQL Oracle

后端 未结 1 1031
有刺的猬
有刺的猬 2020-12-04 01:16

I have a table of the structure:

+---------+--------------+-----------------+---------------+-------+------+
| week_no | long_week_no | week_start_date | week_end_         


        
相关标签:
1条回答
  • 2020-12-04 01:31

    It works perfectly for me with proper use of TO_DATE and DATE values.

    • Never use TO_DATE on a DATE, It will implicitly convert it into string and then back to date using locale-specific NLS format.

    • '01/01/2015' is NOT a DATE, it is a STRING. You must use TO_DATE to explicitly convert it into DATE.

    See what happens:

    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(SYSDATE@!))>TO_DATE(TO_CHAR(SYSDATE@!-1)))
    
    14 rows selected.
    
    SQL>
    

    So, the actual filter applied is filter(TO_DATE(TO_CHAR(SYSDATE@!)) You will get incorrect output due to the implicit conversion based on locale-specific NLS format.

    Anyway, now coming back to your original question.

    For example,

    Let's say your data looks like:

    Setup:

    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>
    

    Table:

    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>
    

    Query to filter the rows based on DATE range:

    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>
    
    0 讨论(0)
提交回复
热议问题