我有一个包含 json 格式字符串的数据库表:
CREATE TABLE `template` (
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`TemplateData` longtext NOT NULL,
PRIMARY KEY (`Id`)
);
INSERT INTO template (Id, TemplateData) VALUES
(1, '[]'),
(2, '[{"type":"template","id":1}]'),
(3, '[{"type":"other", "id":1}]'),
(4, '[{"type":"template","id":3},{"type":"template","id":1}]'),
(5, '[{"type":"template","id":2}]');
http://sqlfiddle.com/#!9/739f3a
背景:这些记录是前端构建动态视图的模板。每个模板都可以包含另一个模板。所以根据上面的数据,记录#2是一个模板,里面使用了另一个模板#1。将其视为可重复使用的部件。
在 json 中,我有一个包含多种类型对象的数组。在我的示例中,有两个不同的变体:{type: "template", id: number}
和{"type": "other", "id": number}
.
服务器架构
生产:
MySQL 服务器版本 8.0.21。
发展:
MariaDB 服务器版本 10.4.11
我想通过 SELECT 检索什么
我需要使用特定其他模板的所有模板的列表。我想选择所有包含$[*].type='template'
AND对象的记录$[*].id=1
。
- 根据给定的记录,我想检索第 2 行和第 4 行,因为它们都包含一个匹配两个参数的对象。复杂性在 #4 上,记录在数组索引 1 处。
- 我不想要#1,因为数组中没有元素
- 我不想要 #3 因为
$[0].type
不是模板
我已经尝试过的
我使用 JSON_SEARCH() 和 JSON_EXTRACT() 进行了一些试验,但无法获得我预期的行:
SELECT
Id,
JSON_EXTRACT(TemplateData,
JSON_UNQUOTE(
REPLACE(JSON_SEARCH(TemplateData,
'all',
'template'),
'.type"',
'.id"'))) AS includedTemplateId
FROM template
HAVING includedTemplateId = 1
仅返回一条 ID 为 2 的记录,但不返回 ID 为 4 的记录,因为带有“all”的 JSON_SEARCH 提供了一个路径数组,但 JSON_EXTRACT 不允许路径为数组。
什么是不可能的
我也尝试使用简单的 LIKE 表达式,但如果 order 或 objects 参数不同(pe: {id: number, type: "template"}
)或使用空格或不同的引号,则问题结束,则 like 不匹配。
附加目标
这将是最完美的结果,如果我在模板 ID #1 之后也获得记录 #5 进行搜索,因为 #5 使用 #2,它使用 #1。但这将是下一个层次。