如何在SQL中基于模糊匹配LIKE条件进行表连接

夜瑶姑娘_7358

夜瑶姑娘_7358

2026-10-29

851人浏览

原创

LIKE不能直接用于JOIN条件,因多数数据库不支持或性能极差;应将模糊逻辑移至WHERE/EXISTS中过滤,或用CTE/子查询预生成匹配对,避免ON中动态拼接导致索引失效。

如何在sql中基于模糊匹配like条件进行表连接

LIKE不能直接用于JOIN条件,但可以用ON子句中嵌套

SQL标准不支持在JOIN语法里把LIKE当连接谓词直接写成ON t1.name LIKE t2.pattern这种形式——它语法合法,但多数引擎(如MySQL 5.7、PostgreSQL)会拒绝执行或报错,因为LIKE右侧必须是常量或参数,不能是列引用(除非该列值本身是完整通配模式且已预处理)。真实可行的方式是把模糊匹配逻辑放在ON子句里,且确保右侧模式字段不含未转义的%或_,否则结果不可控。

  • PostgreSQL允许ON t1.name LIKE t2.pattern,但要求t2.pattern每行都是有效模式(如'john%'),否则匹配行为难以预测
  • MySQL 8.0+支持,但性能极差:无法使用索引,全表扫描+逐行字符串匹配,大表连接时可能卡死
  • 更稳妥的做法是提前用CONCAT('%', t2.keyword, '%')构造模式,再LIKE,但要注意NULL传播:任一操作数为NULL,整个表达式返回NULL,导致连接丢失

用LEFT JOIN + LIKE模拟“关键词包含”关系

典型场景是主表orders要关联到配置表keyword_rules,找出订单标题含任意关键词的规则。这时不能依赖等值连接,得靠LIKE做文本包含判断。

SELECT o.order_id, o.title, r.rule_id, r.keyword
FROM orders o
LEFT JOIN keyword_rules r ON o.title LIKE CONCAT('%', r.keyword, '%');

注意三点:

  • r.keyword必须不含%或_,否则CONCAT后变成多义通配符;若原始数据含这些字符,先用REPLACE(r.keyword, '%', '\%')并加ESCAPE '\'
  • 这个连接会产生笛卡尔式膨胀:一个title匹配多个keyword,就生成多行;需后续用ROW_NUMBER() OVER (PARTITION BY o.order_id ORDER BY r.priority)去重
  • MySQL中CONCAT遇到NULL返回NULL,所以r.keyword IS NOT NULL必须显式加在ON或WHERE里,否则整行被过滤掉

性能陷阱:LIKE左侧字段没索引,右侧又不是前缀匹配

如果写成ON t1.name LIKE CONCAT('%', t2.code, '%'),数据库无法利用t1.name上的B-tree索引,因为通配符在开头。即使t2.code只有几条,t1表也要全扫一遍。

AI Surge Cloud
AI Surge Cloud

AI Surge Cloud是一款面向企业数据科学和 ModelOps 的无代码决策智能平台。

下载
  • 能改用前缀匹配就优先用:ON t1.name LIKE CONCAT(t2.code, '%')——此时t1.name索引可生效(前提是索引建在该字段上)
  • 想查“结尾匹配”,可用RIGHT(t1.name, LENGTH(t2.suffix)) = t2.suffix代替LIKE '%xxx',部分引擎能走索引
  • 真要全文模糊,别硬扛:fulltext索引(MySQL)或tsvector(PostgreSQL)才是正解,LIKE只是临时补丁

替代方案:用REGEXP/RLIKE避免LIKE的语义局限

LIKE只支持%和_,遇到“含数字+字母组合”或“非连续空格分隔”就抓瞎。MySQL的RLIKE、PostgreSQL的~能写更精确的模式。

SELECT u.user_id, u.email
FROM users u
JOIN domains d ON u.email RLIKE CONCAT('@', d.domain_name, '$');

这比LIKE '@%' || d.domain_name更准——防止@gmail.com误匹配@gmail.com.cn。但代价是:

  • 正则引擎比LIKE慢一个数量级,尤其复杂表达式
  • MySQL的RLIKE不走索引;PostgreSQL的~在无函数索引时也全表扫
  • 不同数据库正则语法不兼容(比如MySQL不支持\d,得写[0-9])

真正难的是平衡精度和速度:模糊匹配本身就不该出现在高并发主路径里,要么预计算打标签,要么扔给Elasticsearch。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4603

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

951

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1209

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6581

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3343

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6560

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

9021

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1230

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1072

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习