字符串的Sql格式问题

时间:2017-08-29 13:54:51

标签: plsql

我是SQL格式化功能的新手。我面临一个关于SQL格式的问题。 需要以某种方式修改此SQL字符串,以便它提供类似

的输出
select 'TIME=~XX2015010106000001~XX2015010111000006TCODE=MEAL~XX2015010111450006TCODE=MEAL~XX2015010113000002~' as sub 
from dual);

输出

start=6am meal start=11am Meal end=11.45am end=1pm.

此字符串的问题在于它可能会变化,如TIME=~XX2017080213300001DST=T~XX2017080221300002~

开始的标识符为XX2017080213300001,以01结尾。

结束标识符为XX2017080221300002,以02结尾。

用餐的标识符为XX2015010111000006,以06结尾。

1 个答案:

答案 0 :(得分:0)

为了它的乐趣,我在SQL中使用几个CTE来完成所有这些以分解步骤。如果您愿意,可以将其中一些步骤移至PL / SQL,以便更容易处理。第一个CTE创建一个名为tbl的表,它是原始字符串。第二个创建一个名为elements的表。 regexp_substr调用拉出波浪号分隔的元素,然后regexp_replace调用拉出你需要的小时/分钟。

然后,主查询从元素表中选择,在格式化小时和am / pm时构建字符串。请注意正则表达式处理您提到的备用格式。

需要注意的是,此代码要求所有元素都存在,并且不允许午夜零食。

with tbl(str) as (
  select 'TIME=~XX2015010106000001~XX2015010111000006TCODE=MEAL~XX2015010111450006TCODE=MEAL~XX2015010113000002~' from dual
),
elements(starttime, mealstart, mealend, endtime) as (
  select 
    regexp_replace(regexp_substr(str, '(.*?)(~|$)', 1, 2, NULL, 1), 'XX\d{8}(\d{2})(\d{2})\d{2}01.*', '\1.\2'),
    regexp_replace(regexp_substr(str, '(.*?)(~|$)', 1, 3, NULL, 1), 'XX\d{8}(\d{2})(\d{2})\d{2}06.*', '\1.\2'),
    regexp_replace(regexp_substr(str, '(.*?)(~|$)', 1, 4, NULL, 1), 'XX\d{8}(\d{2})(\d{2})\d{2}06.*', '\1.\2'),
    regexp_replace(regexp_substr(str, '(.*?)(~|$)', 1, 5, NULL, 1), 'XX\d{8}(\d{2})(\d{2})\d{2}02.*', '\1.\2')
  from tbl
)
--select * from elements;
select 'start=' || 
  case 
    when substr(starttime, 1, 2) < 12 then 
      to_char(starttime, 'TM')||'am' 
    when substr(starttime, 1, 2) = 12 then 
      to_char(starttime, 'TM')||'pm'   
    else to_char((starttime - 12), 'TM')||'pm' 
  end ||
  ' meal start=' || 
  case 
    when substr(mealstart, 1, 2) < 12 then 
      to_char(mealstart, 'TM')||'am' 
    when substr(mealstart, 1, 2) = 12 then 
      to_char(mealstart, 'TM')||'pm'       
    else to_char((mealstart - 12), 'TM')||'pm' 
  end ||
  ' Meal end=' ||
  case 
    when substr(mealend, 1, 2) < 12 then 
      to_char(mealend, 'TM')||'am' 
    when substr(mealend, 1, 2) = 12 then 
      to_char(mealend, 'TM')||'pm'       
    else to_char((mealend - 12), 'TM')||'pm' 
  end || 
  ' end=' ||  
  case 
    when substr(endtime, 1, 2) < 12 then 
      to_char(endtime, 'TM')||'am' 
    when substr(endtime, 1, 2) = 12 then 
      to_char(endtime, 'TM')||'pm'       
    else to_char((endtime - 12), 'TM')||'pm' 
  end  ||
  '.' time_string  
from elements;

输出:

TIME_STRING
-------------------------------------------
start=6am meal start=11am Meal end=11.45am end=1pm.