2016-03-21 6 views
-1

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

Insert Into Period (Invoice_No, Period_Date) 
Select Invoice_Seq_No, Inv_Comment 
From Invoices 
Where INV_Comment LIKE '%November 2015'; 

В столбце Inv_Comment содержит свободную форму комментарии и дату в различных форматах, например, «заплачено в ноябре 2015 года или« выплачено по августу »или« июлю 2015 года ». Я пытаюсь скопировать только часть комментария в новую таблицу.

Приведенный выше код только копирует все данные поля Inv_Comment, и я хочу только скопировать дату. Часть даты может быть в одном из трех форматов: MON YYYY, DD.MM.YYYY или только месяц, т.е. MON

Как я могу извлечение только интересующей меня части даты

+0

Сколько у вас есть количество форматов? Вы сделали это так, как будто это бесплатная форма (как обычно для поля комментариев), поэтому ваш первый вопрос заключается в том, как вы определяете, какая часть (ы) комментария является датой вообще? Воля всегда будет последними 13 символами или, по крайней мере, в конце? А может ли комментарий содержать несколько дат? –

+0

Привет Алекс, поле Inv_Comment не является типом данных даты и содержит комментарии, включая дату! Дата находится в трех форматах: «Aug YYYY, DD.MM.YYYY, только месяц e.i. Aug». Это моя проблема, я не могу понять, какая часть (-ы) комментария является датой. Спасибо Dan – Dan

+0

Но всегда в конце? Вы извлекаете каждый формат даты с помощью отдельной вставки? –

ответ

0

Для вашего очень простой пример запроса можно использовать the substr() function, используя длину вашего фиксированного значения, чтобы отсчитать назад от конца строки, так как этот документ описывает:

Если позиция отрицательна, то Oracle рассчитывает назад от конца символа.

Так что вы можете сделать:

select invoice_seq_no, substr(inv_comment, -length('November 2015')) 
from invoices 
where inv_comment like '%November 2015'; 

Но это ясно из комментариев, что вы действительно хотите, чтобы найти все даты, в различных форматах, и не всегда в конце свободной форме текста. Один из вариантов заключается в повторном поиске текста для всех возможных форматов и значений, начиная с наиболее конкретных (например, DD.MM.YYYY), а затем спускается до наименьшего значения (например, только MON). Вы можете вставить только порядковые номера в таблицу начала, а затем повторно обновлять строки, которые еще не установили значения:

insert into period (invoice_no) select invoice_seq_no from invoices; 

update period p 
set period_date = (
    select case when instr(i.inv_comment, '15.09.2015') > 0 then 
    substr(i.inv_comment, instr(i.inv_comment, '15.09.2015'), length('15.09.2015')) 
    end 
    from invoices i 
    where i.invoice_seq_no = p.invoice_no 
) 
where period_date is null; 

затем повторите обновление с другой датой, или более общего ноябрь 2015 шаблоном, и т. д. Но указание каждой возможной даты не будет осуществимо, поэтому вы можете использовать регулярные выражения. Есть, вероятно, лучше модели для этого, но в качестве примера:

update period p 
set period_date = (
    select regexp_substr(i.inv_comment, '[[0-3][0-9][-./][0-1][0-9][-./][12]?[901]?[0-9]{2}') 
    from invoices i 
    where i.invoice_seq_no = p.invoice_no 
) 
where period_date is null; 

, который соответствует (или пытается согласовать) либо похожий ДД.ММ.ГГГГ, после чего может быть:

update period p 
set period_date = (
    select regexp_substr(i.inv_comment, 
    '(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|' 
     || 'Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)([[:space:]]+[12]?[901]?[0-9]{2})?') 
    from invoices i 
    where i.invoice_seq_no = p.invoice_no 
) 
where period_date is null; 

, который соответствует любому короткое или длинное название месяца. Возможно, у вас смешанный случай - авг, авг, AUG - поэтому вы можете захотеть use the match parameter, чтобы сделать его нечувствительным к регистру. Однако это не должно быть полным решением, и вам могут потребоваться дальнейшие форматы. There are some ideas on other questions.

Возможно, вам действительно нужны фактические даты, а это значит, что вам нужно немного поработать, а затем принять отсутствующие годы - возможно, занять год из другого столбца (указать дату?), Если он недоступен в комментариях, хотя это получает немного грязный в конце года. Но вы можете по существу сделать то же самое, просто передавая каждое извлеченное значение через to_date() с маской формата, соответствующей используемому выражению поиска.

Всегда будут ошибки, опечатки, нечетное форматирование и т. Д., Поэтому, даже если этот подход определил большинство шаблонов, вы, вероятно, в конце концов останетесь пустыми, и их нужно будет установить вручную человеком по комментариям; и некоторые из них просто ошибаются. Но именно поэтому даты не должны храниться как строки вообще - их смешивание с другим текстом просто еще хуже.

+0

Спасибо за ваши усилия и помогите Алексу. Я дам вам попытку и дам вам знать результат позже. – Dan

-1

Здесь вы имеете дело со строками, содержащими разрозненную информацию о дате. Может потребоваться несколько струнных операций.

+2

За вопрос с тегом [tag: Oracle]? –

Смежные вопросы