我们的数据库将多天的小时数存储为单个字符串(格式为JSON
,见下文)。我需要提取任何一天的小时数。问题是JSON
没有保证订单中的日期。
我用这种方式尝试substr
和instr
:
SUBSTR(hours_xltd,
INSTR(hours_xltd,'"MONDAY"', 1, 1)+1,
INSTR(hours_xltd,',',1,2) - INSTR(hours_xltd,',',1,1)-1) as Monday
给了我MONDAY":"0800-1800","F
,但我需要的是:
Monday
0800-1800
Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
我需要同样的东西。这是所需的输出(每天在其自己的列上,在我的示例中由管道表示);
monday | tuesday | wednesday | thursday | friday | saturday | sunday
----------------------------------------------------------------------------------
0800-1800 | 0800-1800 | 0800-1800 | 0800-1800 | 0800-1800 | 0800-1800 | 0800-1800
示例数据:
{
"default": {
"standard_hours": {
"TUESDAY":"0800-1800",
"SATURDAY":"0800-1400",
"WEDNESDAY":"0800-1800",
"THURSDAY":"0800-1800",
"SUNDAY":"",
"MONDAY":"0800-1800",
"FRIDAY":"0800-1800"}
}
}
{
"default": {
"standard_hours": {
"MONDAY":"0800-1800",
"TUESDAY":"0800-1800",
"WEDNESDAY":"0800-1800",
"THURSDAY":"0800-1800",
"FRIDAY":"0800-1800",
"SATURDAY":"0800-1800",
"SUNDAY":"0800-1800"}
}
}
请帮我查看代码?我似乎无法解决这个问题。
答案 0 :(得分:0)
让我们跳过一个关于以非结构化格式(如JSON)存储结构化数据并将其转移到解决方案的错误想法的咆哮。
我们可以使用正则表达式提取日期名称和小时。我们知道using regex in production code is a bad thing,所以当我们需要它时,最好尽可能保持清晰。
第一个公用表表达式提取DAY:HOUR字符串并将它们展开到结果集中(这个字符串拆分技巧有几种变体)。第二个CTE将DAY和HOUR字符串分开。主查询使用聚合来旋转行。
with std as ( select id
, regexp_substr(substr(json_str,31), '[^,]+', 1, level) as day_str
from t23
connect by level <= 7 )
, hrs as ( select distinct id
, regexp_substr(day_str, '([A-Z]+)') as d_str
, regexp_substr(day_str, '([0-9\-]+)') as h_str
from std )
select id
, max(case when d_str = 'MONDAY' then h_str end) as monday
, max(case when d_str = 'TUESDAY' then h_str end) as tuesday
, max(case when d_str = 'WEDNESDAY' then h_str end) as wednesday
, max(case when d_str = 'THURSDAY' then h_str end) as thursday
, max(case when d_str = 'FRIDAY' then h_str end) as friday
, max(case when d_str = 'SATURDAY' then h_str end) as saturday
, max(case when d_str = 'SUNDAY' then h_str end) as sunday
from hrs
group by id
order by id
/
请注意,我需要一个ID列才能使pivotimg正常工作。
18 ...
19 order by id
20 /
ID MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY SUNDAY
---------- --------- --------- --------- --------- --------- --------- ---------
1 0800-1800 0800-1800 0800-1800 0800-1800 0800-1800 0800-1400
2 0800-1800 0800-1800 0800-1800 0800-1800 0800-1800 0800-1800 0800-1800
SQL>