2015-04-10 2 views
1

У меня есть таблица структуры:Дата сравнения возвращает необычный результат - 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 | 
+---------+--------------+-----------------+---------------+-------+------+

И когда я запускаю его с любой датой, он вернет правильный период в дополнение к the week_no 51 запись!

Я смущен, почему это происходит. Оба столбца week_start_date и week_end_date типа date.

Fiddle работает должным образом.

+1

Если они уже типа 'date', почему на земле вы звоните' To_Date' на них? –

+0

И, фактически: ['TO_DATE'] (http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions183.htm):« Не используйте функцию TO_DATE со значением DATE для char аргумент " –

+0

@Damien_The_Unbeliever Я бежал без' To_Date' и он возвращает тот же результат. – Hawk

ответ

0

Он отлично работает для меня с надлежащего использования to_date и значения даты.

  • Никогда не используйте TO_DATE на ДАТЕ, она будет неявно преобразовать его в строку, а затем обратно на сегодняшний день, используя локализованный формат NLS.

  • '01/01/2015' НЕ ДАТУ, это 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([email protected]!))>TO_DATE(TO_CHAR([email protected]!-1))) 

14 rows selected. 

SQL> 

Таким образом, фактический фильтр Применяемое фильтр (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> 

запроса для фильтрации строк на основе диапазона дат:

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> 
Смежные вопросы