postgres在带有转义的列中搜索

时间:2015-01-07 19:17:35

标签: postgresql search grep

有没有办法从下面的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
                                                                               +
                                  |

1 个答案:

答案 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)

现在修复你的架构,这样你就可以很好地存储你的数据而不必这样做。