当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL JSON_OVERLAPS 怎样判断数组有共同元素

MySQL JSON_OVERLAPS 怎样判断数组有共同元素

来源:17golang原创 2026-10-15 00:19:55 0浏览 收藏

我在做标签筛选时遇到过一个很容易写反的条件:用户选了一组标签,记录里也存了一组标签,我只想知道两组标签有没有至少一个共同值,却顺手写成了“左边是否包含右边全部元素”。这正是 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_OVERLAPS 与 JSON_CONTAINS 对数组交集和全部包含语义的静态结构说明图
图1:输入集合、匹配语义与 WHERE 条件的关系说明图,展示 JSON_OVERLAPS 的“共同元素”和 JSON_CONTAINS 的“全部元素”差异。

数组判断只需要一个共同元素

最小写法就是把两个合法 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 对数组、对象、标量和 NULL 的静态比较边界说明图
图2:JSON 文档形态、重叠判断与特殊边界的关系说明图,帮助区分共同数组元素、共同键值对、标量相等和 NULL 结果。

什么时候不该用 JSON_OVERLAPS

我在回看旧查询时,通常会先问“业务要的是任意命中,还是全部满足”。如果要求候选数组中的每个元素都必须存在,应该优先考虑 JSON_CONTAINS();如果只是判断一个标量是否属于一个 JSON 数组,MEMBER OF() 的意图更直接。

业务问题更贴近的表达容易踩的边界
两组数组是否至少共享一个元素JSON_OVERLAPS()嵌套数组不做内部部分匹配
候选数组是否全部被目标数组包含JSON_CONTAINS()语义不是“有一个就算”
一个标量是否是数组成员MEMBER OF()数字与字符串类型要分清

如果数组元素本质上是需要排序、统计、去重和建立普通索引的业务实体,长期把它们塞在 JSON 中可能会让查询模型变复杂。JSON_OVERLAPS 解决的是“重叠判断”这一层,不会替代关系表建模。

我的判断清单

  1. 题目里出现“至少一个、任意一个、有交集”,先考虑 JSON_OVERLAPS()。
  2. 题目里出现“全部包含、每个条件都满足”,不要误用交集语义。
  3. 先确认 JSON 元素的类型,数字 6 和字符串 "6" 不要混看。
  4. 把 NULL 单独处理;三值逻辑下的 NULL 不是普通的“不相交”。
  5. 涉及大表时,再围绕 JSON 列路径、多值索引和执行计划做工程取舍。

最终可以把 JSON_OVERLAPS 记成一个很窄但很有用的判断:两个 JSON 文档有没有共同的可比较内容。对数组,它就是“是否存在共同元素”;只要把这个边界和 JSON_CONTAINS 的“全部包含”分开,筛选条件就不容易写反。

相关问题

  • JSON_OVERLAPS 能不能递归判断嵌套数组?不能把它当作递归部分匹配函数。
  • JSON_OVERLAPS 返回 NULL 时怎么筛选?根据业务决定是否用 COALESCE() 明确转换为 0。
  • JSON_OVERLAPS 和 MEMBER OF 有什么区别?前者比较两个 JSON 文档的重叠,后者更适合一个标量查一个数组。
版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
MySQL JSON_VALUE 怎样指定返回类型MySQL JSON_VALUE 怎样指定返回类型
上一篇
MySQL JSON_VALUE 怎样指定返回类型
MySQL 函数索引怎样给 JSON 路径建立可用索引
下一篇
MySQL 函数索引怎样给 JSON 路径建立可用索引
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    474次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    532次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    551次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    505次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    324次使用