您需要 (a) 使用类似regexp_split_to_table
then (b) 使用某些标准匹配哪些部分来拆分数据,因为您没有可以依赖的字段位置顺序。目前我没有看到任何可靠的规则来决定固件版本和机器号是什么;你真的不能说where field <> machine_number
,因为如果机器 1 有固件版本1
,你就不会得到任何结果。
给定虚拟数据:
CREATE TABLE machine_info(data text, machine_no integer);
INSERT INTO machine_info(data,machine_no) (VALUES
('ACT18!!!8246-EN-2.00013151!1^7.00^F5260046959^H1P1O1R1C1Q1L1^1',1),
('BACT/ALERT^A.00^1^^',2)
);
就像是:
SELECT machine_no, regexp_split_to_table(data,'\^')
FROM machine_info;
将为您提供带有机器编号的拆分数据元素表,但随后您需要确定哪些字段是哪些:
machine_no | regexp_split_to_table
------------+------------------------------
1 | ACT18!!!8246-EN-2.00013151!1
1 | 7.00
1 | F5260046959
1 | H1P1O1R1C1Q1L1
1 | 1
2 | BACT/ALERT
2 | A.00
2 | 1
2 |
2 |
(10 rows)
您可能会发现替换的输出regexp_split_to_array
更有用,这取决于您是否可以从字段顺序中获得任何有用的信息以及您打算如何处理数据。
regress=# SELECT machine_no, regexp_split_to_array(data,'\^')
FROM machine_info;
machine_no | regexp_split_to_array
------------+------------------------------------------------------------------
1 | {ACT18!!!8246-EN-2.00013151!1,7.00,F5260046959,H1P1O1R1C1Q1L1,1}
2 | {BACT/ALERT,A.00,1,"",""}
(2 rows)
假设有两个固件版本;版本 1 发送code^blah^fwvers^^
,版本 2 及更高版本发送code^fwvers^blah^blah2^machineno
。然后您可以区分两者,因为您知道版本 1 将最后两个字段留空:
SELECT
machine_no,
CASE WHEN info_arr[4:5] = ARRAY['',''] THEN info_arr[3] ELSE info_arr[2] END AS fw_vers
FROM (
SELECT machine_no, regexp_split_to_array(data,'\^')
FROM machine_info
) string_parts(machine_no, info_arr);
结果:
machine_no | fw_vers
------------+---------
1 | 7.00
2 | 1
(2 rows)
当然,您只提供了两个样本数据,因此真正的匹配规则可能更复杂。考虑编写一个 SQL 函数来提取所需的字段并从传递的数组中返回它们。