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

Sql 仅将某些值从一行复制到另一个表中,sql,oracle,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月支付”、“2015年8月支付”或“2015年7月支付”。我试图做的是仅

我试图将数据从一个表复制到另一个表,这很好,但我只想从其中一列复制某些数据

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月支付”、“2015年8月支付”或“2015年7月支付”。我试图做的是仅将注释的“2015年11月”部分复制到新表中

上述代码仅复制Inv_注释字段的全部数据,我只想复制日期。日期部分可以采用三种格式之一:MON-YYYY、DD.MM.YYYY或仅月份,即MON


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

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

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

如果position为负数,则Oracle从char的末尾向后计数

因此,您可以:

select invoice_seq_no, substr(inv_comment, -length('November 2015'))
from invoices
where inv_comment like '%November 2015';
但从评论中可以清楚地看出,您确实希望以各种格式查找所有日期,但并不总是在自由格式文本的末尾。一个选项是重复搜索文本,以查找所有可能的格式和值,从最具体的(例如DD.MM.YYYY)开始,然后向下搜索最不具体的 (例如,just 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-因此您可能希望使其不区分大小写。但这不是一个完整的解决方案,您可能需要进一步的格式

你可能真的想要实际的日期,这意味着再细分一点,然后假设缺少年份——也许从另一列(订单日期?)中选取年份如果在注释中没有,尽管在年底前后会有点混乱。但基本上你可以做同样的事情,只需将每个提取的值通过
传递到\u date()
,并使用与你使用的搜索表达式匹配的格式掩码


总是会有错误、打字错误、奇怪的格式等等,所以即使这种方法识别了大多数模式,最终也可能会有一些模式留空,需要由查看注释的人手动设置;还有一些是错误的。但这就是为什么日期根本不应该存储为字符串的原因——将它们混合在一起使用其他文本只会让事情变得更糟。

有多少种日期格式?您让它听起来像是自由格式的(对于注释字段来说很正常),所以您的第一个问题是,您如何确定哪一部分注释的最后一个字符是日期?将始终是最后13个字符,或至少在结尾处?注释是否可以包含多个日期?嗨,Alex,Inv_注释字段不是日期数据类型,它包含包括日期在内的注释!日期有三种格式“Aug YYYY,DD.MM.YYYY,仅月份e.i.Aug”“。这是我的问题,我无法确定评论的哪部分是日期。谢谢,但总是在最后?是否使用单独的插入来提取每个日期格式?否日期有时在开头,有时在结尾!我还研究了update语句,但很难确定要将注释的哪一部分复制到新表中!使用单独的insert将很困难,因为有数千行。所以我尝试只使用一个insert语句“如果可能”!AR/AP/GL数据库中是否有其他地方存在发票付款的实际日期?很难相信非结构化评论是找到此信息的唯一地方。对于标记的问题?感谢您的努力和帮助。我将尝试一下,稍后让你知道结果。