2015-11-18 3 views
1

Я новичок в SQL в целом и с Oracle в частности.Oracle SQL - как сравниваются даты

Я создал коллекцию дат =>даты состояла из даты (I)

У меня есть таблица таблица с колоннами даты и доходов.

Когда я делаю запрос,

select sum(revenue) from table where date between date(i) and date(i+1) 

Я не могу получить правильное число => значения меньше, чем правильный.

Когда я делаю

select sum(revenue) from table where date between to_date(date(i),'dd-mm-yyyy') and to_date(date(i+1),'dd-mm-yyyy') 

разный рассказ => Я получаю нулевое значение.

Только

select sum(revenue) from table where date>=date(i) and date<=date(i+1) 

работает хорошо.

Но почему?

+0

Формат по умолчанию - yyyy-mm-dd, поэтому, когда вы его конвертируете, вы получаете другой результат –

+0

Хорошо, я проверю! – paveltr

+0

Еще один вопрос: когда я сделал запрос, а затем посмотрел результаты на выходе, даты представлены как «dd-mm-yyyy». Это сбивает с толку. Таким образом, формат обработки по умолчанию - «yyyy-mm-dd», но формат отображения по умолчанию может быть другим. Я прав? – paveltr

ответ

0

Переменные в вашей коллекции уже являются датами, и вы преобразовываете их снова в даты (это то, что вы никогда не должны делать). Когда вы конвертируете DATE в DATE, переменная ранее преобразуется в строку Oracle, используя маску формата даты по умолчанию. Вы можете увидеть ваши с:

SELECT value 
FROM nls_session_parameters 
WHERE parameter = 'NLS_DATE_FORMAT' 

В моем случае, мой формат даты DD-MM-RR. Так что, если я снова преобразовать дату 01-01-2015 в дату, он будет получить преобразованы так:

1. It will be implicitly converted into a string using the DD-MON-RR mask. I would get 01-01-15. 
2. Then, it will convert the string 01-01-15 into a date using the mask you provide (dd-mm-yyyy). In this case, to_date('01-01-15','dd-mm-yyyy') will return 01-01-0015. 

Это может быть причиной, почему вы не получаете никаких результатов в запросе:

select sum(revenue) from table where date between to_date(date(i),'dd-mm-yyyy') and to_date(date(i+1),'dd-mm-yyyy') 

Если вы использовали вместо этого маску 'dd-mm-rrrr', она преобразует строку 01-01-15 в 01-01-2015, и ваш запрос может вернуть что-то. Я не знаю, это будет зависеть от дат в вашей коллекции.

+0

Четырехзначный формат года 'yyyy' - это четырехзначный формат года. 'rrrr' также принимает только два значения, но это, похоже, не так. –

+0

'to_date (to_date (..))' не имеет никакого смысла. –

+0

Я просто объясняю, почему он не получил никаких результатов в одном из своих запросов, потому что это то, о чем он спрашивает. Конечно, это не нужно. Вы, ребята, прочел мой ответ, прежде чем свалить его? И я думаю, что это может быть связано с маской формата, которую он использует. Пусть он решит, так ли это или нет. – pablomatico

0

Значения даты также содержат время. Поэтому две даты равны только тогда, когда они содержат один и тот же день, и время тоже одно и то же.

Поэтому, когда вы сравниваете «17-11-2015 07:15:00» с «17-11-2015», он не будет равным.

Это объяснило бы для числа строк, возвращаемых быть меньше, чем ожидалось, в своем заявлении:

where date between date(i) and date(i+1) 

дата (плюс время) может быть больше, чем дата (я + 1), даже если день тоже самое.

Если вы не заинтересованы в компоненте времени, используйте функцию trunc(), чтобы исключить компонент времени.Поэтому вы можете написать:

select sum(revenue) from table where trunc(date) between date(i) and date(i+1) 

(Я полагаю, что дата (i) не имеет времени).

2

Почему вы конвертируете значение DATE в значение DATE?

Когда вы to_date(date(i),'dd-mm-yyyy') то происходит следующее:

  1. значение Дата date(i) преобразуется неявно в строку с использованием текущего формата NLS_DATE_FORMAT.

  2. Затем эта строка преобразуется обратно в значение DATE с использованием формата dd-mm-yyyy

Так что, если случайно текущий формат NLS_DATE_FORMAT равно dd-mm-yyyy, то ваш запрос будет работать.

Или, чтобы заставить его работать, выполните ALTER SESSION SET NLS_DATE_FORMAT = 'dd-mm-yyyy';, прежде чем запускать запрос. Тем не менее, это глупая и бесполезная идея конвертировать значение DATE в значение DATE.

+0

Это правильный ответ, а нижняя сторона необоснованна –