如何通过 id 在 MySQL 中的 json 整数数组列中获取相关项目
Posted
技术标签:
【中文标题】如何通过 id 在 MySQL 中的 json 整数数组列中获取相关项目【英文标题】:How to get related items by id inside of json integer array column in MySQL 【发布时间】:2021-02-22 03:51:02 【问题描述】:我的目标是如何获取在 json 数组中有引用的列与其他列之间的关系。简单来说,我有两张表:
table_a
| id | references |
|-----|------------|
| 1 | "[1,3]" |
| 2 | "[2,3]" |
其引用是一个 json 整数数组和表 b
table_b
| id | name |
|-----|----------|
| 1 | "item 1" |
| 2 | "item 2" |
| 3 | "item 3" |
所以,我想获取表 B 的所有项目,这些项目与表 A 的 id 项目相关,例如 1,其 id 在列引用整数数组(如 json)中。
类似这样的:
|-----|----------|
| 1 | "item 1" |
| 3 | "item 3" |
我一直在尝试使用来自docs 的 json_contains、json_extract、json_search 等来实现这一点,我认为问题在于以匹配 json 整数数组中的值的方式。
例如:
SELECT JSON_SEARCH((select references from table_a where id=1), 'one', '3');
必须返回一些东西,但总是返回NULL
,我不明白。我也尝试使用不带引号的3
。
¿有什么想法吗?
我当前的 mysql 版本是5.7.25
提前致谢。
重现的最少代码:
select version();
CREATE TABLE `table_a` (
`id` int(11) NOT NULL,
`references` json NULL
);
CREATE TABLE `table_b` (
`id` int(11) NOT NULL,
`name` text NULL
);
INSERT INTO `table_a` (`id`, `references`) VALUES
(1, '\"[1,3]\"'),
(2, '\"[2,3]\"');
INSERT INTO `table_b` (`id`, `name`) VALUES
(1, 'item_1'),
(2, 'item_2'),
(3, 'item_3');
SELECT * from table_a;
SELECT * from table_b;
select `references` from table_a where id=1;
SELECT JSON_SEARCH((select `references` from table_a where id=1), 'one', '3');
要测试的沙盒:https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=ac557666852fa94e77fdf87158c9abe0
【问题讨论】:
将源数据显示为 CREATE TABLE + INSERT INTO 脚本(或创建在线小提琴)。将所需的输出显示为格式化的文本表格。 为什么使用 json 数组而不是常规的规范化模式? @Akina 我已经更新了。 @Strawberry 我知道。但这是现在数据模型的要求。如果达不到,我会重构它。 我没有看到想要的结果.. 【参考方案1】:不正确(但通过 JSON_VALID 函数检查成功)JSON。
解决方案太可怕了:
SELECT table_b.*
FROM table_a, table_b
WHERE table_a.id = 1
AND JSON_SEARCH(REPLACE(REPLACE(REPLACE(REPLACE(table_a.references, '"', ''), '[', '["'), ']', '"]'), ',', '","'), 'one', table_b.id) IS NOT NULL
fiddle 带有一些解释问题的附加查询。
【讨论】:
【参考方案2】:您可以使用下一个查询作为解决方案:
select
table_a.*,
table_b.*
from table_a
join table_b on JSON_CONTAINS(
CAST(TRIM('"' FROM `references`) as JSON),
CAST(table_b.id as JSON)
)
where table_a.id=2;
由于您的references
字段不是有效的 JSON 类型,您需要将其转换为 JSON,然后才能使用 JSON_CONTAINS 函数。
试试here
【讨论】:
【参考方案3】:您可以先去掉包裹数组的引号,然后将生成的整数与item_
子字符串连接起来,并使用辅助子查询其中一个生成行以便连续获取数组的每个成员,例如
SELECT b.*
FROM
(
SELECT @i := @i + 1 AS rn,
CONCAT('item_',JSON_EXTRACT(JSON_UNQUOTE(`references`),
CONCAT('$[',@i-1,']'))) AS name
FROM information_schema.tables
CROSS JOIN `table_a` AS a
CROSS JOIN (SELECT @i := 0) r
WHERE @i < JSON_LENGTH(JSON_UNQUOTE(`references`)) ) AS a
JOIN `table_b` AS b
ON b.`name` = a.name
Demo
【讨论】:
以上是关于如何通过 id 在 MySQL 中的 json 整数数组列中获取相关项目的主要内容,如果未能解决你的问题,请参考以下文章
java通过jdbc查找数据,查出id值,如何通过整型变量存储这个id值
如何在单个查询中返回 node.js mysql 中的嵌套 json
通过 PHP 将来自 MySQL 的 JSON 解码为 SwiftUI 中的复杂结构