#sql #oracle-sqldeveloper
Вопрос:
Я использую это утверждение в Oracle SQL Developer
select to_char(time,'DD/MM/YY hh24'),count(column) as xyz from table
where to_char(time,'DD/MM/YY')>= '08/04/21'
and to_char(time,'DD/MM/YY')<= '09/04/21'
and column='xyz'
group by to_char(time,'DD/MM/YY hh24')
order by to_char(time,'DD/MM/YY hh24');
То, что я ожидаю, — это результат/таблица, в которой результат упорядочен по времени в порядке возрастания (начиная с самого раннего часа 08/04/21
и заканчивая последним 09/04/21
. Я бы ожидал только записей на несколько дней 08/04/21
и 09/04/21
. Вместо этого я получаю результат, в котором также указаны другие даты, такие как 09/02/21
или 08/12/20
.
Как я могу изменить свой запрос?
Комментарии:
1. Можете ли вы включить некоторые примеры данных для своей таблицы?
2. Для результирующей таблицы или для фактической таблицы, для которой я выполняю запрос?
3. Ну и то и другое, но, по крайней мере, примеры данных для исходной таблицы.
4. вы можете изменить все форматы дат, которые вы возвращаете, на «ГГГГ/ММ/ДД», в противном случае они не сравниваются в соответствии с порядком дат. Кроме того, ваше использование YY чревато проблемой Y2K
Ответ №1:
Вы преобразуете свои собственные значения дат в строки (с двузначными годами!), а затем сравниваете эти строки. Строка «08/12/20» меньше, чем строка «09/04/21».
Сравните свои даты с другими датами, что проще в виде литералов:
select to_char(trunc(time, 'HH'), 'DD/MM/YY HH24'), count(column) as xyz
from table
where time >= date '2021-04-08'
and time < date '2021-04-10'
and column='xyz'
group by trunc(time, 'HH')
order by trunc(time, 'HH');
Я использовал trunc()
для удаления/обнуления частей минуты и секунды, что означает, что вы можете затем сгруппировать и упорядочить по этому значению; и просто преобразовать в строку для отображения в последний момент.
Я также преобразовал to_char(time,'DD/MM/YY')<= '09/04/21'
time < date '2021-04-10'
, а не time < date '2021-04-09'
как ваша версия, все данные с 9 — го числа; что может быть или не быть тем, что вы намеревались-возможно, вы пытались получить один день.
Комментарии:
1. Большое спасибо! Это решило проблему. Но один вопрос: я хотел включить 09/04/2021. Но при использовании
and creationtime <= date '2021-04-09'
строк за 09/04/21 они не включаются при использовании вашего решения. Почему это так?2. Потому
date '2021-04-09'
что 9-го числа полночь, т. е. 2021-04-09 00:00:00; поэтому все, что происходит позже полуночи, не совпадает, даже 2021-04-09 00:00:01. Вот почему я перешел на< date '2021-04-10'
— это включает в себя все, вплоть до полуночи 10 — го, но не включая ее, — и, таким образом, включает в себя все время 9-го.3. Хорошо, большое спасибо за ваше объяснение и помощь 🙂
Ответ №2:
Предполагая , что time
это относится к типу данных date
, вы не хотите делать to_char
это в своем where
предложении или в своем order by
. Как написано, вы выполняете сравнение строк, а не сравнение дат, поэтому вы получаете строки, в которых to_char(time
строка сортируется в алфавитном порядке между двумя значениями, а не строки, в которых дата находится между двумя датами. Сравните с литералами даты или выполните явные to_date
вызовы строковых литералов
Держу пари, что ты действительно хочешь чего-то подобного
select trunc(time, 'HH24'),count(column) as xyz
from table
where time >= date '2021-08-04'
and time <= date '2021-09-04'
and column='xyz'
group by trunc(time, 'HH24')
order by trunc(time, 'HH24');