首页 > 解决方案 > postgres - 在 CASE 子句中使用 SIMILAR TO

问题描述

我有一列包含扫描条形码的字符串。我想找到一个特定的匹配项并在新列中返回字符串“match”和“noMatch”

条形码的正则表达式是

'[0-9]{5,8}\%[0-9]*\%'

例如 13412432%10000%

我的查询是

SELECT 
report."barcode" SIMILAR TO '[0-9]{5,8}\%[0-9]*\%',
(CASE report."barcode" WHEN (report."barcode" SIMILAR TO '[0-9]{5,8}\%[0-9]*\%') THEN 'match'
ELSE 'noMatch'
END) AS matchColumn
FROM report

但是我总是收到这个错误

错误:运算符不存在:text = boolean LINE 3: (CASE report."barcode" WHEN (report."barcode...

提示:没有运算符与给定名称和参数类型匹配。您可能需要添加显式类型转换。SQL 状态:42883 字符:106

我对 SQL 很陌生,所以当文档说它在我想我可以使用 SIMIAR TO 模式匹配之后它需要一个真/假语句时,因为它返回布尔值。

标签: sqlregexpostgresqlpattern-matching

解决方案


我有很好的权威(https://stackoverflow.com/a/12459689/1278553)没有充分的理由使用“类似”。从引用的链接:

SIMILAR TO 是 SQL 标准的一部分,但它的语法非常奇怪,PostgreSQL 支持它的唯一原因是保持标准兼容。在内部,每个 SIMILAR TO 表达式都用正则表达式重写。因此,对于任何给定的 SIMILAR TO 表达式,至少有一个正则表达式可以更快地完成相同的工作。

关于这一点,如果您将其更改为普通的正则表达式,它甚至应该像这样简单:

select
  r.barcode, 
  case
    when r.barcode ~ '\d{5,8}%\d+%' then 'match'
    else 'noMatch'
  end as matchcolumn
from report r

您不需要%使用正则表达式转义字符。

如果您对出现在字符串中间的模式不满意,您可能需要锚定正则表达式的开头和/或结尾:

'^\d{5,8}%\d+%$'

推荐阅读