DuckDB教程:字符串模式匹配
2026/9/9 10:16:58 网站建设 项目流程

当我们不能完全确定需要查找的文本信息时,可以使用模式匹配进行模糊搜索。

DuckDB 提供了四种模式匹配方法:LIKE、SIMILAR TO、GLOB 以及正则表达式函数。

DuckDB 正则表达式函数不仅可以实现复杂的模式匹配,还可以执行字符串的提取、替换等操作,我们后续单独进行介绍。

LIKE

SQL 最常用的模式匹配方式就是采用 LIKE 运算符。假如我们想要知道姓“关”的员工有哪些,可以使用以下查询:

SELECTemp_nameFROMemployeeWHEREemp_nameLIKE'关%';┌──────────┐ │ emp_name │ │varchar│ ├──────────┤ │ 关羽 │ │ 关平 │ │ 关兴 │ └──────────┘

其中,LIKE 关键字指定了一个字符串匹配模式,查找姓名以“关”字开头的员工。

LIKE 运算符支持以下两个通配符,可以用于指定匹配的模式:

  • 百分号(%),表示匹配零个或者多个任意字符。
  • 下划线(_),表示匹配一个任意字符。

以下是一些常用的模式和匹配的字符串:

  • LIKE ‘en%’,匹配以“en”开始的字符串,例如“english”。
  • LIKE ‘%en%’,匹配包含“en”的字符串,例如“length”。
  • LIKE ‘%en’,匹配以“en”结束的字符串,例如“ten”。
  • LIKE ‘Be_’,匹配以“Be”开头,再加上一个任意字符的字符串。例如“Bed”、“Bet”。
  • LIKE ‘_e%’,匹配一个任意字符加上“e”开始的字符串,例如“he”、“year”。

由于百分号和下划线是 LIKE 运算符中的通配符,如果我们查找的模式中包含了“%”或者“_”,需要用到转义字符(escape character)。

转义字符可以将通配符当作普通字符使用。我们首先创建一个测试表:

CREATETABLEt_like(c1VARCHAR(200));INSERTINTOt_like(c1)VALUES('项目进度:25%已完成');INSERTINTOt_like(c1)VALUES('记录日期:2021年5月25日');

t_like 只有一个字段 c1,数据类型为字符串,表中包含两条记录。

假如现在我们需要查找包含“25%”的数据,其中百分号是要查找的内容而不是任意多个字符,可以使用转义字符进行查找:

SELECTc1FROMt_likeWHEREc1LIKE'%25#%%'ESCAPE'#';┌─────────────────────┐ │ c1 │ │varchar│ ├─────────────────────┤ │ 项目进度:25%已完成 │ └─────────────────────┘

ESACPE 关键字为 LIKE 运算符指定了一个 # 符号作为转义字符,因此查找模式中的第二个 % 代表了百分号,其他的 % 则是通配符。

使用 LIKE 运算符进行文本查找时,需要区分英文字母的大小写;如果不想区分大小写,可以使用 ILIKE 运算符。例如,以下语句使用大写字母查找员工的电子邮箱:

SELECTemailFROMemployeeWHEREemailLIKE'M%';┌─────────┐ │ email │ │varchar│ └─────────┘0rowsSELECTemailFROMemployeeWHEREemailILIKE'M%';┌──────────────────┐ │ email │ │varchar│ ├──────────────────┤ │ madai@shuguo.com│ │ mizhu@shuguo.com│ └──────────────────┘

NOT LIKE 运算符可以执行与 LIKE 运算符相反的操作,也就是返回不匹配某个模式的文本。例如,以下语句查找 t_like 表中不包含“25%”的记录:

SELECTc1FROMt_likeWHEREc1NOTLIKE'%25#%%'ESCAPE'#';┌─────────────────────────┐ │ c1 │ │varchar│ ├─────────────────────────┤ │ 记录日期:2021525日 │ └─────────────────────────┘

DuckDB 还提供了以下 PostgreSQL 风格的运算符:~~ 等价于 LIKE,!~~ 等价于 NOT LIKE,~~* 等价于 ILIKE,!~~* 等价于 NOT ILIKE

SIMILAR TO

SIMILAR TO 结合了 LIKE 运算符和正则表达式的特性,提供了字符集、重复匹配、分组、选择等部分正则功能。

前文查找包含“25%”的示例可以使用 SIMILAR TO 实现:

SELECTc1FROMt_likeWHEREc1 SIMILARTO'.*25%.*';┌─────────────────────┐ │ c1 │ │varchar│ ├─────────────────────┤ │ 项目进度:25%已完成 │ └─────────────────────┘

其中,.* 表示匹配零个或者多个任意字符(换行符除外)。

SIMILAR TO 也必须全字符串匹配,例如:

SELECT'abc'SIMILARTO'a';┌───────────────────────────────┐ │ regexp_full_match('abc','a')│ │boolean│ ├───────────────────────────────┤ │false│ └───────────────────────────────┘-- NOT SIMILAR TO执行相反匹配SELECT'abc'NOTSIMILARTO'abc';┌───────────────────────────────────────┐ │(NOTregexp_full_match('abc','abc'))│ │boolean│ ├───────────────────────────────────────┤ │false│ └───────────────────────────────────────┘

另外,~ 运算符等价于 SIMILAR TO,!~ 运算符等价于 NOT SIMILAR TO。

GLOB

GLOB 来源于 Unix Shell 的文件名通配规则,DuckDB 支持使用GLOB 运算符作为一种模式匹配方法。例如:

SELECT'output.csv'GLOB'out*.csv';┌───────────────────────────────┐ │('output.csv'~~~'out*.csv')│ │boolean│ ├───────────────────────────────┤ │true│ └───────────────────────────────┘

从查询结果可以看出,GLOB 运算符等价于三重波浪号(~~~)。

DuckDB 还提供了一个 glob 函数,可以用于搜索文件名。例如:

SELECT*FROMglob('*');┌─────────────────────────┐ │file│ │varchar│ ├─────────────────────────┤ │.\databases.csv │ │.\databases2.csv │ │.\duckdb-cheatsheet.pdf │ │.\duckdb-docs.pdf │ │.\duckdb-releases.csv │ │.\duckdb.exe │ │.\hr.duckdb │ │.\hr.duckdb.wal │ │.\output.csv │ │.\test.duckdb │ │.\ui │ └─────────────────────────┘11rows

以上查询返回了当前工作目录下的所有文件。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询