Запрос по дате со строкой даты и времени

#sql #oracle #date

#sql #Oracle #Дата

Вопрос:

У меня есть таблица базы данных, где один из столбцов содержит значения даты. Формат строки — «ГГГГ-ММ-ДД ЧЧ24: MI: SS». Я хотел бы иметь возможность выбрать другой столбец, В котором дата равна XXXX / XX / XX без времени. Я не очень хорошо знаком с SQL, поэтому я не совсем уверен, как это сделать. Следующий код — это то, с помощью чего я сейчас пытаюсь выполнить запрос:

 SELECT COUNT(DISTINCT(NETID)) EARLIEST_MONTHLY_DATE FROM REPORT_SERVICE_USAGE

WHERE EARLIEST_MONTHLY_DATE LIKE ' 14-03-14%' 
  

Я не знаю, было бы проще сократить время (мне это не обязательно нужно), но если бы я это сделал, мне, возможно, понадобятся некоторые рекомендации о том, как это можно сделать.

Комментарии:

1. Тип столбца — date datetime или text? varchar?

2. Какой поставщик (Oracle, MS-SQL и т.д.)?

3. Это поставщик Oracle. Тип столбца — дата.

Ответ №1:

Наиболее эффективный способ сделать это выглядит следующим образом:

 where earliest_monthly_date >= to_date('2014-03-14', 'yyyy-mm-dd')
and earliest_monthly_date < to_date('2014-03-15', 'yyyy-mm-dd')
  

Таким образом, вы не беспокоитесь о каких-либо временных частях ваших полей даты. Вот другой способ, который эквивалентен, но медленнее:

 where trunc(earliest_monthly_date) = to_date('2014-03-14', 'yyyy-mm-dd')
  

Функция trunc отнимает часть времени, но использование функций в предложении where, подобных этому, медленнее, чем использование самих полей.

Вы также должны понимать, что даты — это, по сути, числа с плавающей запятой. Они отформатированы в строки, чтобы их могли прочитать люди. Вы также можете выполнить собственное форматирование. В oracle используется функция to_char().

Глядя на код в вашем вопросе, есть три синтаксические ошибки. Первый,

 COUNT(DISTINCT(NETID)) 
  

должно быть

 COUNT(DISTINCT NETID)   
  

Далее за ним должна следовать запятая,

 COUNT(DISTINCT NETID),
  

и, наконец, вам нужно предложение group by

 group by earliest_monthly_date
  

Это синтаксис. Вероятно, вам нужно что-то вроде этого:

 select to_char(earliest_monthly_date, 'yyyy-mm-dd') thedate
, count(distinct netid) countOfNetId
from report_service_usage
where earliest_monthly_date >= to_date('2014-03-14', 'yyyy-mm-dd')
and earliest_monthly_date < to_date('2014-03-15', 'yyyy-mm-dd')
group by to_char(earliest_monthly_date, 'yyyy-mm-dd')
  

Комментарии:

1. У меня есть небольшой вопрос. Я использовал 2013-09-01 и 2013-09-30 для тестирования. Почему, когда я запрашиваю earliest_monthly_date >= to_date(‘2013-09-01’, ‘гггг-мм-дд’) и earliest_monthly_date < to_date(‘2013-10-01’, ‘гггг-мм-дд’), он возвращает другое число, чем earliest_monthly_date >= to_date(‘2013-09-01’, ‘гггг-мм-дд’ ) и earliest_monthly_date <= to_date(‘2013-09-30’, ‘гггг-мм-дд’)?