当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL 怎样判断两个 JSON 数组是否有交集

MySQL 怎样判断两个 JSON 数组是否有交集

来源:17golang原创 2026-10-17 22:10:10 0浏览 收藏

MySQL 怎样判断两个 JSON 数组是否有交集

判断两个 JSON 数组是否至少共享一个元素,可以使用 JSON_OVERLAPS(array_a, array_b):有共同元素返回 1,没有返回 0,任一参数是 SQL NULL 时返回 NULL。它给出的是相交判断,不是交集元素列表。数字与字符串不能靠隐式转换凑成匹配,嵌套数组也不会被自动拍平后逐个比较。

下面以商品标签筛选为例:用户选择“收纳”或“照明”,商品只要拥有其中一个标签就应出现。场景为原创说明,不涉及真实线上事故;SQL 按 MySQL 8.4 文档编写,制作文章时未连接数据库执行。官方文档地址:https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html。

标签筛选漏命中,先确认要的是“任意一个”

假设某商品标签是“收纳、桌面”,用户选择“收纳、照明”。这个商品应该命中,因为共享“收纳”,不要求它同时具有“照明”。这时需要的是任意相交语义。把所有选中标签都必须包含的条件直接拿来用,容易让筛选结果意外变少。

-- 最小写法:两个 JSON_ARRAY 都产生真正的 JSON 数组。
SELECT JSON_OVERLAPS(
    JSON_ARRAY('收纳', '桌面'),
    JSON_ARRAY('收纳', '照明')
) AS has_overlap;

这一表达式的预期是 1。不要用 LIKE 搜索序列化后的数组文本:那比较的是字符片段,可能把标签子串、引号和嵌套内容都算进去,并没有表达数组元素相同的业务要求。

快速区分无交集、类型不符和未知值

遇到“肉眼相同却不命中”,先看元素类型。JSON 数字 208 与 JSON 字符串 "208" 是不同输入,不能把 JSON_OVERLAPS 当成自动清洗器。应在数据入口统一标签或编号的类型,而不是查询失败后把整份 JSON 转成字符串比较。

-- 数字与字符串不会因为显示相似而自动匹配,预期为 0。
SELECT JSON_OVERLAPS(JSON_ARRAY(208), JSON_ARRAY('208')) AS mixed_types;

-- 相同字符串标签可以匹配,预期为 1。
SELECT JSON_OVERLAPS(JSON_ARRAY('208'), JSON_ARRAY('208')) AS same_type;

-- SQL NULL 表示未知输入;这里预期返回 NULL,而不是 0。
SELECT JSON_OVERLAPS(NULL, JSON_ARRAY('收纳')) AS unknown_input;

-- 空数组没有可共享元素,预期为 0。
SELECT JSON_OVERLAPS(JSON_ARRAY(), JSON_ARRAY('收纳')) AS empty_input;

SQL NULL 与 JSON null 也不同。前者是 SQL 层的未知值,后者可以是 JSON 数组中的一个元素。若标签业务不允许 null 元素,应在写入契约中拒绝,而不是将它解释为“没有标签”。若业务明确规定未知输入也按不匹配处理,才在输出层使用 COALESCE;否则会丢失排查所需的未知状态。

JSON数组元素、类型约束与结果状态的静态关系图
图一:输入元素和结果状态分属不同边界;连线表达比较约束,不是 SQL 执行顺序或实测截图。

把条件放入查询,并单独检查嵌套元素

先用一份只读样例固定预期:记录 11 应命中,记录 12 不命中,记录 13 因未知标签返回 NULL。这样不需要创建表、修改数据或借用生产账号。

-- 只读样例:先保留每条记录的原始判断结果,方便看见 NULL。
WITH sample_items AS (
    SELECT 11 AS id, JSON_ARRAY('收纳', '桌面') AS tags
    UNION ALL
    SELECT 12, JSON_ARRAY('餐厨')
    UNION ALL
    SELECT 13, NULL
)
SELECT id, JSON_OVERLAPS(tags, JSON_ARRAY('收纳', '照明')) AS matched
FROM sample_items
ORDER BY id;

接入已有表时,假设 item_catalog.tags 是 JSON 标签数组,查询可以写成下面这样。表名和字段名是示例约定,不表示你的数据库已经存在这些对象。应用程序应绑定序列化后的 JSON 参数,不要拼接未经处理的用户文本。

-- 仅返回判断为 1 的记录;SQL NULL 不会被 WHERE 当成真。
SELECT id, tags
FROM item_catalog
WHERE JSON_OVERLAPS(tags, JSON_ARRAY('收纳', '照明')) = 1;

如果得到的数量仍不符合预期,再查看数组是否实际嵌套。一个子数组作为外层数组的元素时,需要按完整元素理解,不能把内部某个值相同当作整个子数组相同。

-- 左侧唯一元素是子数组 [208,309],右侧是数字 208;预期为 0。
SELECT JSON_OVERLAPS('[[208,309]]', '[208]') AS not_flattened;

-- 两侧共享完整子数组 [208,309],预期为 1。
SELECT JSON_OVERLAPS('[[208,309]]', '[[208,309]]') AS nested_equal;

如果业务真正要比较所有层级的叶子编号,就已经超出了当前数组元素比较的口径。不要只换一个函数名便声称覆盖递归数据;先定义需要比较的层级,再单独设计提取规则。

扁平与嵌套数组在元素粒度上的组成差异结构图
图二:外层元素可以是标量,也可以是整个子数组;该组成结构图说明为何内部部分重合不等于元素相同。

替换筛选条件后异常,怎样安全回退

本次修复应只涉及读取条件,不需要改写标签数据。发布前保留原查询和新查询的差异,并使用相同的固定样本比较返回 ID,而不只比较总数。如果新条件导致不符合业务口径的记录进入结果,先恢复旧谓词或关闭对应查询变更,再调查元素类型与选中条件的定义。

不要为了让样例命中就批量转换生产标签、删除 NULL 或展开全部嵌套结构;这会把查询语义调整变成数据迁移,回退难度明显增大。本文不提供这样的数据改写命令。若服务器不识别 JSON_OVERLAPS,先确认实际数据库产品与版本是否支持,不将 MySQL 8.4 的示例直接套到其他数据库。

结果恢复要看固定样本,不用告警消失代替判断

读者在自己的环境运行时,应分别确认共同字符串、无共同元素、数字与字符串、嵌套子数组、SQL NULL、空数组这几类输入。若用于线上筛选,观察既有错误率和查询耗时即可,不为这次修复虚构新的“性能提升比例”。

JSON_OVERLAPS 返回 1 只说明语义命中,不证明查询一定高效,也不证明自动走索引。这里不扩展索引设计;数据量较大时,应结合自己的表结构与执行计划另做性能评估,不能把一个正确的函数表达式当成通用优化结论。

把数组类型约定留在接口文档里

输入形态应如何解释本例判断口径
共享同一字符串标签至少一个元素相同1
完全不同的标签没有共享元素0
数字与同样字面的字符串类型不同,不自动转换0
SQL NULL输入未知NULL
空数组没有候选元素0

重复标签会让结果变成 2 吗?

不会。JSON_OVERLAPS 是布尔式相交判断,不统计共享元素数量;重复项不改变这个输出类型。

能直接得到交集列表吗?

不能。需要列表时,应另外定义展开、比较和去重规则;不要把返回 1 当成交集中的某个值。

为什么 WHERE 没返回 NULL 标签记录?

因为未知结果不满足“等于 1”。是否把未知当作不匹配,应由业务契约决定,而不是为了让数量一致而临时改数据。

这次标签筛选的关键,不是写出更长的 SQL,而是确认“任意相交”的定义,并把元素类型和层级约定写清。固定样本、只读比较和可回退的谓词变更,能让这个小功能保持清晰可维护。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
MySQL JSON_TABLE 展开数组后怎样避免重复行MySQL JSON_TABLE 展开数组后怎样避免重复行
上一篇
MySQL JSON_TABLE 展开数组后怎样避免重复行
MySQL 隐藏索引怎样无风险评估查询计划
下一篇
MySQL 隐藏索引怎样无风险评估查询计划
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之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模型性能。
    507次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    569次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    593次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    546次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    364次使用