【发布时间】:2022-01-23 02:09:27
【问题描述】:
我有一张如下图的表格:
CREATE TABLE IF NOT EXISTS `tb_test` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`content` json NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `tb_test` (`id`, `content`) VALUES (1, '[{"name": "vabcx", "value": 100}, {"name": "uabcw", "value": 150}, {"name": "xxx", "value": 110}]');
INSERT INTO `tb_test` (`id`, `content`) VALUES (2, '[{"name": "jabcl", "value": 130}, {"name": "xabcf", "value": 150}, {"name": "uuu", "value": 110}]');
INSERT INTO `tb_test` (`id`, `content`) VALUES (3, '[{"name": "pabcg", "value": 100}, {"name": "qabct", "value": 100}, {"name": "hhh", "value": 300}]');
我有两个要求:
- 查找名称中包含“abc”且所有名称中包含“abc”的值大于120的行。即对于上表,选择id=2的行。
- 查找名称包含“abc”且名称中至少有一个包含“abc”的值大于120的行。即,对于上表,选择id=1和id=2的行。
我尝试了下面的sql,但是因为name和value是分开处理的,所以3行都被选中了。
mysql> SELECT * FROM tb_test WHERE content->'$**.name' LIKE '%abc%'and content->'$**.value' > 120;
+----+---------------------------------------------------------------------------------------------------+
| id | content |
+----+---------------------------------------------------------------------------------------------------+
| 1 | [{"name": "vabcx", "value": 100}, {"name": "uabcw", "value": 150}, {"name": "xxx", "value": 110}] |
| 2 | [{"name": "jabcl", "value": 130}, {"name": "xabcf", "value": 150}, {"name": "uuu", "value": 110}] |
| 3 | [{"name": "pabcg", "value": 100}, {"name": "qabct", "value": 100}, {"name": "hhh", "value": 300}] |
+----+---------------------------------------------------------------------------------------------------+
另外,对于需求2,我不想使用下面的sql,因为以后可能会有$[4],$[5]......。
SELECT * FROM tb_test WHERE content->'$[0].name' LIKE '%abc%'AND content->'$[0].value' > 120 OR content->'$[1].name' LIKE '%abc%'AND content->'$[1].value' > 120 OR content->'$[2].name' LIKE '%abc%'AND content->'$[2].value' > 120;
我也知道将内容存储为下表可以解决问题。
CREATE TABLE IF NOT EXISTS `tb_test01` (
`ass_id` bigint(20) unsigned NOT NULL COMMENT 'associated ID',
`name` VARCHAR(32) NOT NULL,
`value` int(11) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
但我想知道如何使用 sql 和 json,或者任何其他好的方法来解决我的问题。
我从here学到了一些json搜索功能。
期待您的帮助,提前感谢您。
【问题讨论】: