
当我们不能完全确定需要查找的文本信息时可以使用模式匹配进行模糊搜索。DuckDB 提供了四种模式匹配方法LIKE、SIMILAR TO、GLOB 以及正则表达式函数。DuckDB 正则表达式函数不仅可以实现复杂的模式匹配还可以执行字符串的提取、替换等操作我们后续单独进行介绍。LIKESQL 最常用的模式匹配方式就是采用 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 运算符。例如以下语句使用大写字母查找员工的电子邮箱SELECTemailFROMemployeeWHEREemailLIKEM%;┌─────────┐ │ email │ │varchar│ └─────────┘0rowsSELECTemailFROMemployeeWHEREemailILIKEM%;┌──────────────────┐ │ email │ │varchar│ ├──────────────────┤ │ madaishuguo.com│ │ mizhushuguo.com│ └──────────────────┘NOT LIKE 运算符可以执行与 LIKE 运算符相反的操作也就是返回不匹配某个模式的文本。例如以下语句查找 t_like 表中不包含“25%”的记录SELECTc1FROMt_likeWHEREc1NOTLIKE%25#%%ESCAPE#;┌─────────────────────────┐ │ c1 │ │varchar│ ├─────────────────────────┤ │ 记录日期2021年5月25日 │ └─────────────────────────┘DuckDB 还提供了以下 PostgreSQL 风格的运算符~~ 等价于 LIKE!~~ 等价于 NOT LIKE~~* 等价于 ILIKE!~~* 等价于 NOT ILIKESIMILAR TOSIMILAR TO 结合了 LIKE 运算符和正则表达式的特性提供了字符集、重复匹配、分组、选择等部分正则功能。前文查找包含“25%”的示例可以使用 SIMILAR TO 实现SELECTc1FROMt_likeWHEREc1 SIMILARTO.*25%.*;┌─────────────────────┐ │ c1 │ │varchar│ ├─────────────────────┤ │ 项目进度25%已完成 │ └─────────────────────┘其中.* 表示匹配零个或者多个任意字符换行符除外。SIMILAR TO 也必须全字符串匹配例如SELECTabcSIMILARTOa;┌───────────────────────────────┐ │ regexp_full_match(abc,a)│ │boolean│ ├───────────────────────────────┤ │false│ └───────────────────────────────┘-- NOT SIMILAR TO执行相反匹配SELECTabcNOTSIMILARTOabc;┌───────────────────────────────────────┐ │(NOTregexp_full_match(abc,abc))│ │boolean│ ├───────────────────────────────────────┤ │false│ └───────────────────────────────────────┘另外~ 运算符等价于 SIMILAR TO!~ 运算符等价于 NOT SIMILAR TO。GLOBGLOB 来源于 Unix Shell 的文件名通配规则DuckDB 支持使用GLOB 运算符作为一种模式匹配方法。例如SELECToutput.csvGLOBout*.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以上查询返回了当前工作目录下的所有文件。