【问题标题】:Use Regex from a column in Redshift使用 Redshift 列中的正则表达式
【发布时间】:2017-04-22 14:19:13
【问题描述】:

我在 Redshift 中有 2 个表,其中一个有一个包含正则表达式字符串的列。我想像这样加入他们:

select *
from one o
join two t
on o.value ~ t.regex

但是这个查询会抛出一个错误:

[Amazon](500310) Invalid operation: The pattern must be a valid UTF-8 literal character expression
Details: 
 -----------------------------------------------
  error:  The pattern must be a valid UTF-8 literal character expression
  code:      8001
  context:   
  query:     412993
  location:  cgx_impl.cpp:1911
  process:   padbmaster [pid=5211]
  -----------------------------------------------;

据我在文档中搜索了解到,正则表达式运算符 ~ 的右侧必须是字符串文字。

这样就可以了:

select *
from one o
where o.value ~ 'regex'

这会失败:

select *
from one o
where 'regex' ~ o.value

有没有办法解决这个问题?我错过了什么?

谢谢!

【问题讨论】:

  • two.regex 的列类型和排序规则是什么?你能隔离出哪个值引发错误并告诉我们该值,还是所有值都出错?

标签: regex amazon-redshift literals


【解决方案1】:

这是我正在使用的解决方法。也许它不是超级快,但它确实有效:

首先创建一个函数:

CREATE FUNCTION is_regex_match(pattern text, s text) RETURNS BOOLEAN IMMUTABLE AS $$
  import re
  return True if re.search(pattern, s) else False
$$ LANGUAGE plpythonu;

然后像这样使用它(o.value 包含一个正则表达式模式):

select *
from one o
where is_regex_match(o.value, 'some string');

【讨论】:

    【解决方案2】:

    您可以尝试使用内置函数regexp_substr() https://docs.aws.amazon.com/redshift/latest/dg/REGEXP_SUBSTR.html

    select *
    from one o
    join two t
    on regexp_substr(o.value, t.regex) <> ''
    

    添加原始查询的编辑示例

    似乎这些字段在构建时必须显式转换为 varchars。

    with fake_table as (
      SELECT 'sample value'::varchar as value, '[a-z]'::varchar as pattern
    )
    
    SELECT * 
    , regexp_substr(value, pattern)
    FROM
      fake_table
    WHERE 
      regexp_substr(value, pattern) <>''
    

    【讨论】:

    • 我遇到了同样的问题。我尝试了这个解决方案,仍然得到同样的错误:“模式必须是有效的 UTF-8 文字字符表达式”
    • 听起来你的字符串有一些非标准字符。你能用这个错误隔离一行,并支付字符串吗?
    • CREATE TABLE for_regex(value VARCHAR(100), pattern VARCHAR(100)); INSERT INTO for_regex(value, pattern) VALUES ('abc', '[a-z]'); SELECT * FROM for_regex WHERE regexp_substr(value, pattern) &lt;&gt; ''; 。执行最后一个statememnt后,出现错误(是的,我这里有一个where子句,但是和join一样)。
    • 好的,问题是您必须将值显式转换为 varchars。我不确定为什么你的 SQL 不起作用,但只有在将 ::varchar 添加到 both 字段之后,我才开始使用它。 (更新答案中的代码块)
    • 当值和模式显式写入与regexp_substr 相同的查询中时,它可以工作(即使查询包含子查询或WITH 子句)。但是将值和模式插入到真实表中,然后选择它们并尝试与regexp_substr 一起使用是行不通的。至少我不能让它工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 2016-08-18
    • 2018-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多