有没有办法从下面的select中为“site”执行类似grep的操作(这样只会从数据中返回“site = *”)?
rr=# select thename,encode(thedata, 'escape') from
management_data.datas limit 2;
thename | thedata
-----------------------------------------------------------------------------------
Alexander | #
+
| #Fri Mar 15 14:58:18 PDT 2014
+
| BUs=ALL
+
| site=33$36$354$380$357$360$36$353$36$38$39$34$31$355
+
Anthony | #
+
| #Mon Jan 05 13:33:00 PST 2015
+
| mem=12000
+
| site=50$5$1$50
+
|
答案 0 :(得分:0)
鉴于测试数据成功往返:
WITH somerow(name, blobofgarble) AS (
SELECT
TEXT 'Alexander',
BYTEA E'#\n#Fri Mar 15 14:58:18 PDT 2014\nBUs=ALL\nsite=33$36$354$380$357$360$36$353$36$38$39$34$31$355\n'
)
SELECT name, encode(blobofgarble, 'escape') FROM somerow;
现在,我无法想象为什么您将此信息存储为bytea
而不是text
字段,但是......好吧,我猜必须有一个理由。我将依赖于简化的假设,即数据在转义时可以被视为相当明确的text
,因为否则," line"是垃圾,你的问题毫无意义。
有了这个假设,可以使用regexp_split_to_table
拆分新行,获得更加明智的数据:
WITH (...)
SELECT name, garblepart FROM somerow, regexp_split_to_table(encode(blobofgarble, 'escape'), E'\n') AS garblepart;
name | garblepart
-----------+------------------------------------------------------
Alexander | #
Alexander | #Fri Mar 15 14:58:18 PDT 2014
Alexander | BUs=ALL
Alexander | site=33$36$354$380$357$360$36$353$36$38$39$34$31$355
Alexander |
(5 rows)
(这是一个隐式的LATERAL
查询,所以它只适用于PostgreSQL 9.3及以上版本。)
现在,您可以使用非常普通的操作来查找感兴趣的行并提取所需的部分,在这种情况下使用更多模式匹配:
WITH (...)
SELECT
name, substring(garblepart from '=(.*$)')
FROM somerow,
regexp_split_to_table(encode(blobofgarble, 'escape'), E'\n') AS garblepart
WHERE garblepart LIKE 'site=%';
name | substring
-----------+-------------------------------------------------
Alexander | 33$36$354$380$357$360$36$353$36$38$39$34$31$355
(1 row)
现在修复你的架构,这样你就可以很好地存储你的数据而不必这样做。