mysql - 如何使用 MySQL 选择 JSON 数组中对象的键

标签 mysql arrays json

我正在使用一个表,该表使用 JSON 列将问题答案存储为对象数组,其中键是问题 strong> 的值就是答案

问题是用户生成的,因此 key 实际上可以是任何东西。

例如:

<表类=“s-表”> <标题> id 问题 <正文> 1 [{“最喜欢的食物?”:“披萨”},{“年龄?”:“12”}] 2 [{"你住在哪里?": "法国"}, {"你还好吗?", "不,不太好"}]

我试图弄清楚是否可以使用 MySQL 来查询此数据并获得如下所示的结果:

<表类=“s-表”> <标题> 问题 回答 <正文> “最喜欢的食物?” “披萨” “年龄?” “12” “你住在哪里?” “法国” “你还好吗?” “不,不是真的”

我认为这不会太难,但很快意识到这可能超出了我对 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;

问题是这只给我对象的值而不是像这样的键:

<表类=“s-表”> <标题> 问题 回答 <正文> “披萨” “披萨” “12” “12” “等” “等”

顺便说一句,我没有充分的理由这样做。纯粹是挠痒痒,因为我看到这个问题出现并认为它会很简单 - 也许确实如此 - 我只是不知道如何做到这一点!

先谢谢🙏

最佳答案

如果你以不同的方式存储 JSON 会更容易:

<表类=“s-表”> <标题> id 问题 <正文> 1 [{"question": "最喜欢的食物?", "answer": "披萨"}, {"question": "年龄?": "answer": "12"}] 2 [{"question": "你住在哪里?", "answer": "法国"}, {"question": "你还好吗?", "answer": "不,不太好"}]

然后您可以使用 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,而只是将每个问题和答案单独存储在一行中,那么会更容易:

<表类=“s-表”> <标题> id applicant_id 问题 回答 <正文> 1 1 最喜欢的食物? 披萨 2 1 年龄? 12 3 2 你住在哪里? 法国 4 2 你还好吗? 不,不是真的

现在人们太渴望使用 JSON。普通的行和列更容易、更高效。


回复您的评论:

是的,我相信这是可能的,但麻烦大于其值(value)。

您不能直接使用 JSON_TABLE(),因为对象没有一致的键名称。

所以你需要:

  1. 通过连接到一组整数,将数组拆分为每行一个对象。例如,使用临时表或 CTE。
  2. 对于每个对象,使用 JSON_KEYS() 将键名称获取到数组中。
  3. 在调用 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/

相关文章:

mysql - 在 MySQL 数据库列中将比率存储为数字

java - 在 for (Array - java) 上创建条件

javascript - 使用javascript在文本框中显示数据

php - 使用 MySQL 或 PHP 防止重复条目的正确方法

php - 如何从mysql中的原始数据中仅选择第一行

java - toString 不打印 JApplet 中的实际数组值

php - 我可以将数组绑定(bind)到 PDO 查询中的 IN() 条件吗?

php - 解析 Google Images API Json PHP

android - 如何在 Android 中为以下 JSON 字符串创建用于 GSON 解析的对象类?

php - 优化 Mysql 搜索查询