SQL формат даты изменения внутри строки - PullRequest
0 голосов
/ 21 февраля 2012

Я хотел бы преобразовать строку, содержащую даты в SQL, выбрать из базы данных Oracle 11g.

Пример исходной строки (CLOB):

"1.12.2011 - event 1
 2.2.2012 - event 2
 13.3.2012 - event 44"

Желаемый вывод:

"20111201 - event 1
 20120202 - event 2
 20120313 - event 44"

Есть ли лучший (более быстрый) способ, чем использование 4 отдельных замен?

regexp_replace(regexp_replace(regexp_replace(regexp_replace(my_string,
'(\d\d)\.(\d\d)\.(20\d\d)', '\3\2\1'),
'(\d\d)\.(\d)\.(20\d\d)', '\30\2\1'),
'(\d)\.(\d\d)\.(20\d\d)', '\3\20\1'),
'(\d)\.(\d)\.(20\d\d)', '\30\20\1')

Ответы [ 4 ]

1 голос
/ 21 февраля 2012

Особенно, если вы используете сгустки, вы должны быть осторожны, если вы не уверены в данных там.

Однако, если ваш сабл выглядит только так, вам нужно три regexp_replace, чтобы это сработало;это также будет намного более динамичным.Просто явно укажите цифры, используя [[:digit:]], затем укажите минимальное и максимальное количество раз, когда эти цифры могут быть там, используя {1,2}.

. Тогда будет работать следующее:

select regexp_replace( 
          regexp_replace( 
             regexp_replace( my_string
                           , '([[:digit:]]{1,2})\.([[:digit:]]{1,2})\.(20[[:digit:]]{2})'
                           , '\3-\2-\1')
                        , '-([[:digit:]]{1}(-|$))'
                        , '0\1' )
                     , ('-')
                     , '')
  from dual

Это означает, что:

  • совпадение (группа 1) 1 или 2 цифры
  • совпадение с полной остановкой.
  • совпадение (группа 2) 1 или 2 цифры
  • соответствуют полной остановке
  • соответствуют (группа 3) 20 + 2 цифры.

Затем возьмитеисключить только группы 1, 2 и 3, т.е. игнорировать полные остановки и вернуться затем в порядке 3, 2, 1 с дефисом

, а затем заменить любой [digit], за которым следует либо дефис, либоконец строки, т. е. количество цифр составляет только 1 с -0[digit].

Наконец, заменить все дефисы.

Отдельно от этого я согласен с tbone .Было бы гораздо разумнее хранить эти данные в отдельной таблице (event_id number, event_date date).Любые строковые преобразования просты без возможности ошибиться, в отличие от этой ситуации, и данные легко запрашивать и сравнивать.

0 голосов
/ 25 ноября 2015

Я предпочитаю двухуровневое регулярное выражение для части даты:

select regexp_replace(
           regexp_replace( my_string,
               '([[:digit:]]{1,2})\.([[:digit:]]{1,2})\.(20[[:digit:]]{2})',
               '\3-0\2-0\1' ),
           '(20[[:digit:]]{2})-0?([[:digit:]]{2})-0?([[:digit:]]{2})',
           '\3\2\1' )
from dual;

Демо

0 голосов
/ 26 апреля 2012

нет лучших вариантов (как правильных, так и читаемых) с лучшей производительностью - или, если есть, никого не волнует ..

0 голосов
/ 21 февраля 2012

Возможно, попробуйте сделать:

select to_char(to_date('13.3.2011', 'DD.MM.YYYY'),'YYYYMMDD') from dual;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...