PostgreSQL根据模式将单列值拆分为多列

时间:2019-10-03 15:33:34

标签: sql postgresql sas

我正在对带有显式传递SQL的Postgres数据库使用SAS EG。我有一张乱七八糟的桌子,我需要为最终用户“清理”。表中的一列(varchar255)具有多个粉碎在一起的日期值。大多数值只有一个日期值(即10/11/2018),但有些看起来像这样(8/11/201810/6/2019)。我需要将它们拆分出来,但是除了模式之外,没有分隔符可以拆分,但是即使那样它也是可变长度的,所以我不知道该怎么做。基本上,序列中的第一个日期可以是(1-2个数字月份/ 1-2个数字日期/ 4个年份),然后是下一个日期。如何拆分这些并用定界符将它们分开,以便随后执行split_to_array,计算数组中单独值的最大数量,然后制作适当数量的新列以容纳单独的日期?通常,我会提供一个代码示例,但在这种情况下,我什至不知道从哪里开始解析它们。

原始值示例:

row1 6/4/2017
row2 8/11/201810/6/2019
row3 10/16/20134/12/201812/18/2019

期望值示例:

row1 6/4/2017
row2 8/11/2018, 10/6/2019
row3 10/16/2013, 4/12/2018, 12/18/2019

谢谢!

2 个答案:

答案 0 :(得分:2)

您应该能够做出与日期匹配的正则表达式。这在SAS中有效。请注意,它添加了一个额外的逗号,但是您可以删除它,找出如何制作更复杂的正则表达式,或者只是忽略该额外的逗号。

WANT=prxchange('s/(\d{1,2}\/\d{1,2}\/\d{4})/$1,/',-1,HAVE);

类似Postgres的有regex_replace()函数,所以类似的东西应该可以工作

regexp_replace(HAVE,'(\d{1,2}/\d{1,2}/\d{4})','\1,','g') as WANT

答案 1 :(得分:1)

使用PostgreSQL函数regexp_match

来自PostgreSQL文档https://www.postgresql.org/docs/current/functions-matching.html

  

在通常情况下,您只希望整个匹配的子字符串或无匹配的NULL,则写类似

     

SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1];
  regexp_match
  --------------
  barbeque

可能需要几个选择表达式,当您尝试提取越来越多的日期字符串时,正则表达式模式中要捕获的日期模式组之前有越来越多的日期模式。

regexp_match(mashed, '(\d{1,2}/\d{1,2}/\d{4})`) as datestring1,
regexp_match(mashed,  '\d{1,2}/\d{1,2}/\d{4}(\d{1,2}/\d{1,2}/\d{4})`) as datestring2,
etc …