Сравнить месяц во временной метке

#oracle #timestamp

#Oracle #временная метка

Вопрос:

У меня есть таблица с типом данных временной метки, и мне нужно сравнить значение месяца, чтобы выбрать все значения таблицы. Например, созданное поле и требуется получить все строки, созданные в период с ноября по декабрь любого года. Пробовал с приведенным ниже запросом, и это не сработало.

выберите * из имя_таблицы, где TO_CHAR(created_time, ‘mon’) в (‘nov’,’dec’)

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

1. mon Модель формата зависит от национальных настроек, работает ли это? to_char(created_time, 'mon', 'NLS_DATE_LANGUAGE = american')

2. Я могу получить месяц в предложении select, но не могу использовать результат для сравнения в предложении where

Ответ №1:

Использовать EXTRACT :

 SELECT *
FROM   table_name
WHERE  EXTRACT( MONTH from created_time ) IN ( 11, 12 )
  

Или вы можете использовать TO_CHAR( created_time, 'MM' ) для получения числового значения месяца (и не беспокоиться о языковых настройках, как это было бы при MON модели формата):

 SELECT *
FROM   table_name
WHERE  TO_CHAR( created_time, 'MM' ) IN ( '11', '12' )
  

db<>скрипта

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

1. Я полагаю, что в TO_CHAR значения 11, 12 в предложении where без кавычек.

2. @Shankar TO_CHAR возвращает строковое значение, поэтому IN предложение также может быть строковым. Если вы не используете кавычки, то Oracle должен выполнить неявное преобразование числа в строку, и вы создаете (немного) больше работы при оценке запроса.

Ответ №2:

Что ж, есть несколько способов добиться этого.

1.Использование функции nlsparam of to_char

Аргумент ‘nlsparam’ указывает язык, на котором возвращаются названия месяцев и дней и сокращения.

Пример

 SQL> create table t ( c1 timestamp ) ;

Table created.

SQL> alter session set nls_timestamp_format = 'dd.mm.yyyy hh24:mi:ss.rr' ;

Session altered.

SQL> insert into t values ( systimestamp - 30 ) ;

1 row created.

SQL>  insert into t values ( systimestamp ) ;

1 row created.

SQL> select * from t ;

C1
---------------------------------------------------------------------------
30.07.2020 09:29:35.20
29.08.2020 09:29:42.20

SQL> select value from nls_database_parameters where parameter='NLS_LANGUAGE' ;

VALUE
--------------------------------------------------------------------------------
AMERICAN

SQL> select c1 , to_char(c1, 'mon' , 'NLS_DATE_LANGUAGE = american') as mon from t ;

C1
---------------------------------------------------------------------------
MON
------------
30.07.2020 09:29:35
jul

29.08.2020 09:29:42
aug
  

2. Однако, чтобы избежать зависимости от языка, вы можете использовать extract и сравнивать номер месяца, который одинаков на любом языке. В этом случае вам необходимо преобразовать временную метку в дату, но перед этим вам нужно установить nls_timestamp_format определенный формат.

 SQL> alter session set nls_timestamp_format = 'dd.mm.yyyy hh24:mi:ss';

Session altered.

SQL>  select c1 , extract(month from to_date(c1,'dd.mm.yyyy hh24:mi:ss')) from t ;

C1
---------------------------------------------------------------------------
EXTRACT(MONTHFROMTO_DATE(C1,'DD.MM.YYYYHH24:MI:SS'))
----------------------------------------------------
30.07.2020 09:29:35
                                                   7

29.08.2020 09:29:42
                                                   8
  

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

1. выберите c1 , to_char(c1, ‘mon’, ‘NLS_DATE_LANGUAGE = американский’) в качестве mon из t, где to_char(c1, ‘mon’, ‘NLS_DATE_LANGUAGE = американский’) = ‘июль’ Будет ли работать предложение where?

2. это должно работать, если данные, хранящиеся в вашей таблице, соответствуют языку nls_language