MySQL JSON_OVERLAPS 怎样判断数组有共同元素
我在做标签筛选时遇到过一个很容易写反的条件:用户选了一组标签,记录里也存了一组标签,我只想知道两组标签有没有至少一个共同值,却顺手写成了“左边是否包含右边全部元素”。这正是 JSON_OVERLAPS() 适合解决的场景。
官方地址:https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html
对于两个 JSON 数组,JSON_OVERLAPS(a, b) 只要找到一个或多个相同数组元素就返回 1,完全没有共同元素时返回 0。它和 JSON_CONTAINS() 的差别可以先记成一句话:前者是“有交集”,后者更接近“候选集合全部被包含”。
先把“有一个”和“全都有”分开
这两个函数都能出现在 WHERE 条件里,但它们表达的业务关系不同。比如文章标签是 ["go", "mysql", "json"],用户筛选条件是 ["mysql", "redis"]:
JSON_OVERLAPS()看到共同的mysql,结果为1。JSON_CONTAINS()如果要求左侧包含右侧整个数组,因为缺少redis,结果为0。
我通常先画出“集合关系”再决定函数,避免被函数名带偏。下面这张图是静态语义说明图,不是数据库运行截图。

数组判断只需要一个共同元素
最小写法就是把两个合法 JSON 数组直接传给函数。下面的三个例子分别覆盖有交集、仍然有交集、完全无交集的情况:
-- 用数组交集判断是否至少命中一个标签
SELECT JSON_OVERLAPS('[1, 3, 5, 7]', '[2, 5, 7]') AS has_common;
-- 只要存在一个共同值,结果就是 1
SELECT JSON_OVERLAPS('[1, 3, 5, 7]', '[2, 6, 7]') AS has_common;
-- 没有共同数组元素时,结果是 0
SELECT JSON_OVERLAPS('[1, 3, 5, 7]', '[2, 6, 8]') AS has_common;
这里不需要先把数组拆成行再连接,也不需要手工拼接一串 OR。对业务来说,返回值只承担一个布尔判断:是否存在交集。
需要特别注意嵌套数组。JSON_OVERLAPS 比较的是数组元素,嵌套数组作为一个整体参与比较,不会因为内部出现部分数字就算命中。例如 [[1,2],[3,4],5] 与 [1,[2,3],[4,5]] 的外层元素没有完全相同的值,因此不能把它理解成递归查找。
对象、标量和 NULL 会改变你对结果的直觉
虽然标题关注数组,但实际写查询时很容易把 JSON 文档形态混在一起。JSON_OVERLAPS 的静态关系可以归纳为:数组看共同元素,对象看共同键值对,两个标量做相等比较;任一参数为 SQL NULL 时,结果也是 NULL。
-- 对象需要键和值同时相同,只有 d:10 这一对完全重合
SELECT JSON_OVERLAPS(
'{"a": 1, "b": 10, "d": 10}',
'{"c": 1, "e": 10, "f": 1, "d": 10}'
) AS object_overlap;
-- 两个标量相等时返回 1
SELECT JSON_OVERLAPS('5', '5') AS scalar_overlap;
-- SQL NULL 会让判断结果变成 NULL,而不是 0
SELECT JSON_OVERLAPS(NULL, '[1, 2]') AS null_result;
对象场景尤其容易误判:两个对象都出现键 a,但值分别为 1 和 5,这并不算共同键值对。换句话说,JSON_OVERLAPS 不是“只看 key 名称”。
数组和标量混用时,标量可以被当成一个数组元素参与比较,但 JSON 类型不会自动互转:
-- 数字 6 可以作为一个数组元素参与重叠判断
SELECT JSON_OVERLAPS('[4, 5, 6, 7]', '6') AS number_overlap;
-- 字符串 "6" 与数字 6 类型不同,不会自动转换后命中
SELECT JSON_OVERLAPS('[4, 5, "6", 7]', '6') AS string_number_boundary;
SELECT JSON_OVERLAPS('[4, 5, 6, 7]', '"6"') AS number_string_boundary;
放进 JSON 列的 WHERE 条件
真正的业务查询通常不是比较两个字面量,而是比较表里的 JSON 列和一个查询参数。假设 article.tags 保存文章标签数组,可以这样表达“至少命中一个用户筛选标签”:
-- tags 保存 JSON 数组,筛选条件只要求存在一个共同标签 SELECT id, title FROM article WHERE JSON_OVERLAPS(tags, '["mysql", "json"]');
如果筛选值来自应用参数,应让驱动或预处理语句负责绑定,而不是把用户输入直接拼进 SQL。这个例子只展示 JSON_OVERLAPS 的关系,不把参数转义细节伪装成固定字符串。
在 InnoDB 的 JSON 列上,官方文档还说明了:把 JSON_OVERLAPS 放在 WHERE 中时,可以朝多值索引方向优化。是否真的被采用,要结合列路径、索引定义、数据分布和执行计划判断,不能因为函数支持索引就默认每次查询都会变快。

什么时候不该用 JSON_OVERLAPS
我在回看旧查询时,通常会先问“业务要的是任意命中,还是全部满足”。如果要求候选数组中的每个元素都必须存在,应该优先考虑 JSON_CONTAINS();如果只是判断一个标量是否属于一个 JSON 数组,MEMBER OF() 的意图更直接。
| 业务问题 | 更贴近的表达 | 容易踩的边界 |
|---|---|---|
| 两组数组是否至少共享一个元素 | JSON_OVERLAPS() | 嵌套数组不做内部部分匹配 |
| 候选数组是否全部被目标数组包含 | JSON_CONTAINS() | 语义不是“有一个就算” |
| 一个标量是否是数组成员 | MEMBER OF() | 数字与字符串类型要分清 |
如果数组元素本质上是需要排序、统计、去重和建立普通索引的业务实体,长期把它们塞在 JSON 中可能会让查询模型变复杂。JSON_OVERLAPS 解决的是“重叠判断”这一层,不会替代关系表建模。
我的判断清单
- 题目里出现“至少一个、任意一个、有交集”,先考虑
JSON_OVERLAPS()。 - 题目里出现“全部包含、每个条件都满足”,不要误用交集语义。
- 先确认 JSON 元素的类型,数字
6和字符串"6"不要混看。 - 把
NULL单独处理;三值逻辑下的NULL不是普通的“不相交”。 - 涉及大表时,再围绕 JSON 列路径、多值索引和执行计划做工程取舍。
最终可以把 JSON_OVERLAPS 记成一个很窄但很有用的判断:两个 JSON 文档有没有共同的可比较内容。对数组,它就是“是否存在共同元素”;只要把这个边界和 JSON_CONTAINS 的“全部包含”分开,筛选条件就不容易写反。
相关问题
- JSON_OVERLAPS 能不能递归判断嵌套数组?不能把它当作递归部分匹配函数。
- JSON_OVERLAPS 返回 NULL 时怎么筛选?根据业务决定是否用
COALESCE()明确转换为 0。 - JSON_OVERLAPS 和 MEMBER OF 有什么区别?前者比较两个 JSON 文档的重叠,后者更适合一个标量查一个数组。
MySQL JSON_VALUE 怎样指定返回类型
- 上一篇
- MySQL JSON_VALUE 怎样指定返回类型
- 下一篇
- MySQL 函数索引怎样给 JSON 路径建立可用索引
-
- 数据库 · MySQL | 27分钟前 | mysql事务 · InnoDB · mysql READ ONLY transaction_read_only 只读事务 START TRANSACTION
- MySQL 只读事务怎样减少误写风险
- 439浏览 收藏
-
- 数据库 · MySQL | 32分钟前 | MySQL · mysql SET PERSIST SET PERSIST_ONLY RESET PERSIST mysqld-auto.cnf SET GLOBAL
- MySQL SET PERSIST 和 SET GLOBAL 有什么区别
- 378浏览 收藏
-
- 数据库 · MySQL | 32分钟前 |
- MySQL ANSI_QUOTES 开启后标识符为何变化
- 279浏览 收藏
-
- 数据库 · MySQL | 35分钟前 |
- MySQL INSERT ... ON DUPLICATE KEY UPDATE 怎样区分插入和更新
- 181浏览 收藏
-
- 数据库 · MySQL | 40分钟前 | MySQL · 执行计划 · 查询优化 · mysql Hash Join 哈希连接 EXPLAIN FORMAT=TREE block_nested_loop join_buffer_size
- MySQL 哈希连接在什么条件下生效
- 185浏览 收藏
-
- 数据库 · MySQL | 43分钟前 | MySQL · csv · 数据库运维 · 数据导入 · 批量导入 字段映射 MySQL LOAD DATA CSV首行 IGNORE 1 LINES
- MySQL LOAD DATA 怎样跳过 CSV 首行
- 420浏览 收藏
-
- 数据库 · MySQL | 51分钟前 | MySQL · sql优化 ·
- MySQL 索引提示怎样只影响特定连接表
- 432浏览 收藏
-
- 数据库 · MySQL | 52分钟前 | MySQL · JSON · RETURNING COLLATE 生成列 JSON_VALUE CAST MySQL 函数索引 JSON 路径
- MySQL 函数索引怎样给 JSON 路径建立可用索引
- 136浏览 收藏
-
- 数据库 · MySQL | 1小时前 |
- MySQL 窗口帧怎样计算按日期的累计值
- 393浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · mysql 分组查询 窗口函数 ROW_NUMBER 派生表 Top N
- MySQL 派生表怎样为每组取前几条记录
- 230浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 474次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 532次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 551次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 505次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 324次使用
-
- MySQL JSON_TABLE 展开数组时如何保留缺失字段
- 2026-09-10 501浏览
-
- MySQL 分区表怎么处理跨分区唯一键:分区列约束与建表取舍
- 2026-08-30 501浏览
-
- MySQL权限管理设置全攻略
- 2026-03-29 501浏览
-
- MySQL分片实现方法及常见方案解析
- 2025-06-24 501浏览
-
- MySQL表空间碎片怎么清理?超详细优化教程
- 2025-06-13 501浏览
