簡體   English   中英

日期比較返回異常結果-SQL Oracle

[英]Date comparison returns unusual result - SQL Oracle

我有一張表格的結構:

+---------+--------------+-----------------+---------------+-------+------+
| week_no | long_week_no | week_start_date | week_end_date | month | year |
+---------+--------------+-----------------+---------------+-------+------+
| 1       | 1A           | 01/01/2015      | 03/01/2015    | JAN   | 2015 |
| 1       | 1B           | 04/01/2015      | 10/01/2015    | JAN   | 2015 |
| 2       | 2            | 11/01/2015      | 17/01/2015    | JAN   | 2015 |
| 3       | 3            | 18/01/2015      | 24/01/2015    | JAN   | 2015 |
| ..      | ..           | ..              | ..            | ..    | ..   |
| 51      | 51           | 14/12/2014      | 20/12/2015    | DEC   | 2014 |
+---------+--------------+-----------------+---------------+-------+------+

當我運行以下語句時:

SELECT * 
FROM   loy_period 
WHERE  To_date('15/04/2015', 'DD/MM/YYYY') BETWEEN 
       To_date(week_start_date, 'DD/MM/YYYY') AND 
       To_date(week_end_date, 'DD/MM/YYYY'); 

SELECT * 
FROM   loy_period 
WHERE  To_date('15/04/2015', 'DD/MM/YYYY') BETWEEN 
       week_start_date AND 
       week_end_date; 

它返回以下內容:

+---------+--------------+-----------------+---------------+-------+------+
| week_no | long_week_no | week_start_date | week_end_date | month | year |
+---------+--------------+-----------------+---------------+-------+------+
|      51 | 51           | 14/12/2014      | 20/12/2015    | DEC   | 2014 |
|       1 | 1A           | 01/01/2015      | 03/01/2015    | JAN   | 2015 |
+---------+--------------+-----------------+---------------+-------+------+

當我使用任何日期運行它時,除了 week_no 51記錄 ,它還會返回正確的時間段!

我很困惑為什么會這樣。 這兩列week_start_dateweek_end_date類型的date

小提琴按預期工作。

正確使用TO_DATE和DATE值,它對我來說非常有效。

  • 永遠不要在DATE上使用TO_DATE ,它將隱式地將其轉換為字符串,然后使用特定於語言環境的NLS格式恢復為最新

  • '01/01/2015'不是DATE,而是STRING。 您必須使用TO_DATE將其顯式轉換為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(SYSDATE@!))>TO_DATE(TO_CHAR(SYSDATE@!-1)))

14 rows selected.

SQL>

因此,實際應用的過濾器是filter(TO_DATE(TO_CHAR(SYSDATE @!))。由於基於特定於語言環境的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>

查詢以根據DATE范圍過濾行:

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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM