仅将某行中的某些值复制到另一个表中

时间:2016-03-21 08:13:04

标签: sql oracle

我正在尝试将数据从一个表复制到另一个表,这可以正常工作,但我只想从列中的一个复制某些数据。

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

Inv_Comment列包含自由格式的评论和不同格式的日期,例如"于2015年11月支付或" 8月"或" 2015年7月"。我要做的是只复制" 2015年11月"对新表的评论的一部分。

上面的代码只复制Inv_Comment字段的整个数据,我只想复制日期。日期部分可以采用以下三种格式之一:MON YYYY,DD.MM.YYYY或仅月份即MON

如何只提取我感兴趣的日期部分?

2 个答案:

答案 0 :(得分:0)

对于非常简单的示例查询,您可以使用the substr() function,使用固定值的长度从字符串末尾开始计数,如该文档所述:

  

如果position为负数,那么Oracle将从char结尾向后计数。

所以你可以这样做:

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年11月模式等重复更新。但是指定每个可能的日期是不可行的,所以你可以使用正则表达式。可能有更好的模式,但作为一个例子:

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;

匹配(或尝试匹配)任何看起来像DD.MM.YYYY的东西,然后是:

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,Aug,AUG - 所以你可能希望use the match parameter使它不区分大小写。这不应该是一个完整的解决方案,你可能需要更多的格式。 There are some ideas on other questions

你可能真的想要实际日期,这意味着分解更多,然后假设缺少年份 - 如果评论中没有它可能从另一列(订单日期?)中取出年份,尽管如此年底前变得有些乱。但你基本上可以做同样的事情,只需通过to_date()传递每个提取的值,格式掩码与你正在使用的搜索表达式匹配。

总会有错误,拼写错误,奇怪的格式化等等,所以即使这种方法确定了大多数模式,你也可能最终得到一些空白,并且需要由人工手动设置看着评论;还有一些是错的。但这就是为什么日期根本不应该存储为字符串 - 将它们与其他文本混合在一起只会让事情变得更糟。

答案 1 :(得分:-1)

在这里,您要处理包含不同日期信息的字符串。可能需要几个字符串操作。

相关问题