在 Postgres 中解析字符串

Parse String in Postgres

在 PostgreSQL 数据库中,我有一个 table 单元格包含每天的工作时间,它的值是这样的:

---
Fri:
- '8'
- '9'
- '10'
- '11'
- '12'
- '13'
- '14'
- '15'
- '16'
- '17'
Mon:
- '8'
- '9'
... etc ...
Wed:
- '8'
- '9'
- '10'
- '11'
- '12'
- '13'
- '14'
- '15'
- '16'
- '17'

如何阅读或将其放入另一个 table 中:

dow start end
1 08:00:00 18:00:00
2 08:00:00 18:00:00
3 08:00:00 18:00:00

其中 dow 代表星期几,例如 1 代表星期一,2 代表星期二等。

创建起始的代码示例table:

CREATE TABLE test
(
  wh text
);

INSERT INTO test (wh ) VALUES ('---
Fri:
- ''8''
- ''9''
- ''10''
- ''11''
- ''12''
- ''13''
- ''14''
- ''15''
- ''16''
- ''17''
Mon:
- ''8''
- ''9''
- ''10''
- ''11''
- ''12''
- ''13''
- ''14''
- ''15''
- ''16''
- ''17''
Sat:
- ''8''
- ''9''
- ''10''
- ''11''
- ''12''
- ''13''
Thu:
- ''8''
- ''9''
- ''10''
- ''11''
- ''12''
- ''13''
- ''14''
- ''15''
- ''16''
- ''17''
Tue:
- ''8''
- ''9''
- ''10''
- ''11''
- ''12''
- ''13''
- ''14''
- ''15''
- ''16''
- ''17''
Wed:
- ''8''
- ''9''
- ''10''
- ''11''
- ''12''
- ''13''
- ''14''
- ''15''
- ''16''
- ''17''');

创建目的地的代码示例table:

CREATE TABLE working_hours
(
  dow integer NOT NULL,
  hour_start time ,
  hour_end time,
  CONSTRAINT pk_dow_working_hours PRIMARY KEY (dow)
);

INSERT INTO working_hours (dow, hour_start, hour_end, customer_user ) VALUES (1, '08:00:00', '18:00:00');
INSERT INTO working_hours (dow, hour_start, hour_end, customer_user ) VALUES (2, '08:00:00', '18:00:00');
INSERT INTO working_hours (dow, hour_start, hour_end, customer_user ) VALUES (3, '08:00:00', '18:00:00');
INSERT INTO working_hours (dow, hour_start, hour_end, customer_user ) VALUES (4, '08:00:00', '18:00:00');
INSERT INTO working_hours (dow, hour_start, hour_end, customer_user ) VALUES (5, '08:00:00', '18:00:00');
INSERT INTO working_hours (dow, hour_start, hour_end, customer_user ) VALUES (6, '08:00:00', '14:00:00');

通过一些正则表达式魔法,文本可以转换为 json 数组。

那么只需要处理 json.

select 
  case l2.WeekDay
  when 'Mon' then 1
  when 'Tue' then 2
  when 'Wed' then 3
  when 'Thu' then 4
  when 'Fri' then 5
  when 'Sat' then 6
  when 'Sun' then 7
  end as DayOfWeek
, (l2.HourStart||':00')::time as TimeStart
, (l2.HourEnd||':00')::time as TimeEnd
from test
cross join lateral (
  select ('['||
   regexp_replace(
    regexp_replace(
     regexp_replace(wh, 
      '[^\w:]*([\w:]+)[^\w:-]*','"",','g')
    , '"(\w+):",', '{"day":"","hours":[','g')
    , '"(,[{])|",$', '"]}','g')
    ||']')::json as whjs
) l1
cross join lateral (
  select 
    value->>'day' as WeekDay
  , value->'hours'->>0  as HourStart
  , value->'hours'->>-1  as HourEnd
  from json_array_elements(l1.whjs)
) l2
dayofweek timestart timeend
5 08:00:00 17:00:00
1 08:00:00 17:00:00
6 08:00:00 13:00:00
4 08:00:00 17:00:00
2 08:00:00 17:00:00
3 08:00:00 17:00:00

测试 db<>fiddle here