Snowflake:如何筛选table1.col1中为table2.col2子串的行?
解决方案:筛选table1中存在于table2任意行子串的记录
核心思路
用EXISTS子查询判断table1的每个单字串是否能在table2的任意多行文本中找到匹配,结合LIKE和通配符实现子串匹配。
通用SQL写法(适用于MySQL、PostgreSQL、SQL Server等主流数据库)
SELECT DISTINCT t1.col1 FROM table1 t1 WHERE EXISTS ( SELECT 1 FROM table2 t2 WHERE t2.col2 LIKE CONCAT('%', t1.col1, '%') );
说明
DISTINCT:避免table1中重复的单字串被多次返回(如果table1存在重复行)CONCAT('%', t1.col1, '%'):给table1的单字串前后加百分号通配符,实现任意位置的子串匹配EXISTS:只要table2中存在任意一行满足匹配条件,就保留table1对应的行
不同数据库的细节补充
- MySQL/MariaDB:如需区分大小写,可使用
LIKE BINARY替代LIKE,示例:SELECT DISTINCT t1.col1 FROM table1 t1 WHERE EXISTS ( SELECT 1 FROM table2 t2 WHERE t2.col2 LIKE BINARY CONCAT('%', t1.col1, '%') ); - PostgreSQL:也可用
POSITION(t1.col1 IN t2.col2) > 0替代LIKE写法,效果一致:SELECT DISTINCT t1.col1 FROM table1 t1 WHERE EXISTS ( SELECT 1 FROM table2 t2 WHERE POSITION(t1.col1 IN t2.col2) > 0 ); - SQL Server:字符串拼接可用
+号替代CONCAT(CONCAT在SQL Server 2012及以上版本也支持):SELECT DISTINCT t1.col1 FROM table1 t1 WHERE EXISTS ( SELECT 1 FROM table2 t2 WHERE t2.col2 LIKE '%' + t1.col1 + '%' );
性能提示
如果table2数据量较大,逐行匹配效率可能偏低,可考虑:
- 给table2.col2创建全文索引,使用数据库对应的全文搜索函数(如MySQL的
MATCH()、PostgreSQL的to_tsvector)优化查询速度 - 提前预处理table2的文本内容,提取所有可能的子串存入临时表,再与table1关联查询
内容的提问来源于stack exchange,提问作者Matthew Coudert
相关产品推荐
相关产品推荐

