MySQL 怎样判断两个 JSON 数组是否有交集
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;否则会丢失排查所需的未知状态。

把条件放入查询,并单独检查嵌套元素
先用一份只读样例固定预期:记录 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,而是确认“任意相交”的定义,并把元素类型和层级约定写清。固定样本、只读比较和可回退的谓词变更,能让这个小功能保持清晰可维护。
MySQL JSON_TABLE 展开数组后怎样避免重复行
- 上一篇
- MySQL JSON_TABLE 展开数组后怎样避免重复行
- 下一篇
- MySQL 隐藏索引怎样无风险评估查询计划
-
- 数据库 · MySQL | 59分钟前 |
- MySQL 逻辑备份怎样处理并发写入窗口
- 444浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · 主从复制 · replica_parallel_workers MySQL 复制延迟
- MySQL 复制延迟怎样按并行工作线程分析
- 488浏览 收藏
-
- 数据库 · MySQL | 1小时前 |
- MySQL 一致性快照怎样影响长事务读
- 214浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · explain · optimizer trace MySQL 查询计划
- MySQL 查询计划选择异常时怎样读取 optimizer trace
- 466浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · 执行计划 · 查询优化 · 分区表 · mysql partition pruning 分区裁剪 RANGE COLUMNS EXPLAIN partitions
- MySQL 分区裁剪未生效时怎样定位条件写法
- 124浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · JSON · mysql JSON数组 JSON_TABLE 重复行 NESTED PATH FOR ORDINALITY
- MySQL JSON_TABLE 展开数组后怎样避免重复行
- 406浏览 收藏
-
- 数据库 · MySQL | 1小时前 |
- MySQL 用 LAG 比较相邻记录时怎样处理首行
- 303浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · ROW_NUMBER MySQL窗口函数 每组最新记录 RANK DENSE_RANK Top-N
- MySQL 窗口函数取每组最新记录时怎样稳定排序
- 265浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 507次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 569次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 593次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 546次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 364次使用
-
- 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浏览
