我正在使用一个表,该表使用 JSON 列将问题和答案存储为对象数组,其中键是问题 strong> 的值就是答案。
问题是用户生成的,因此 key 实际上可以是任何东西。
例如:
我试图弄清楚是否可以使用 MySQL 来查询此数据并获得如下所示的结果:
我认为这不会太难,但很快意识到这可能超出了我对 MySQL 的了解!
这里的主要困难是,当 key 被埋在这样的数组中时,我似乎无法弄清楚如何提取 key ,而且我不知道 key 的名称是什么。
我能得到的最接近的是一个如下所示的查询:
select j.* from ats_applicants,
JSON_TABLE(additional_fields, "$[*].*" COLUMNS ( question varchar(100) PATH '$', answer varchar(100) PATH '$'))
as j where additional_fields is not null;
问题是这只给我对象的值而不是像这样的键:
顺便说一句,我没有充分的理由这样做。纯粹是挠痒痒,因为我看到这个问题出现并认为它会很简单 - 也许确实如此 - 我只是不知道如何做到这一点!
先谢谢🙏
最佳答案
如果你以不同的方式存储 JSON 会更容易:
然后您可以使用 JSON_TABLE() 将字段映射到列中:
SELECT j.*
FROM ats_applicants
CROSS JOIN JSON_TABLE(additional_fields, '$[*]' COLUMNS (
question varchar(100) PATH '$.question',
answer varchar(100) PATH '$.answer'
)
) AS j
WHERE additional_fields IS NOT NULL;
但是,如果您根本不使用 JSON,而只是将每个问题和答案单独存储在一行中,那么会更容易:
现在人们太渴望使用 JSON。普通的行和列更容易、更高效。
回复您的评论:
是的,我相信这是可能的,但麻烦大于其值(value)。
您不能直接使用 JSON_TABLE(),因为对象没有一致的键名称。
所以你需要:
- 通过连接到一组整数,将数组拆分为每行一个对象。例如,使用临时表或 CTE。
- 对于每个对象,使用 JSON_KEYS() 将键名称获取到数组中。
- 在调用 JSON_EXTRACT() 时使用这些键名称。
下面是我需要工作的解决方案。在我看来,使用需要如此复杂的代码来完成最简单的任务的数据模型是完全愚蠢的。
WITH RECURSIVE n AS (
SELECT 0 AS n
UNION SELECT n+1 FROM n WHERE n < 1
),
pair AS (
SELECT id, n.n, JSON_EXTRACT(additional_fields, CONCAT('$[', n.n, ']')) AS pair
FROM n CROSS JOIN ats_applicants
),
q AS (
SELECT id, n, JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(pair), '$[0]')) AS question
FROM pair
)
SELECT id, q.question, JSON_UNQUOTE(JSON_EXTRACT(pair.pair, CONCAT('$."', q.question, '"'))) AS answer
FROM q JOIN pair USING (id, n)
输出:
+----+--------------------+----------------+
| id | question | answer |
+----+--------------------+----------------+
| 1 | Age? | 12 |
| 1 | Favourite Food? | Pizza |
| 2 | Are you ok? | No, not really |
| 2 | Where do you live? | France |
+----+--------------------+----------------+
关于mysql - 如何使用 MySQL 选择 JSON 数组中对象的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71519284/