#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' )
Комментарии:
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