将 JSON "dictonary" 拆分为单独的行
Split JSON "dictonary" into separate rows
同事们。
我有一个像这样的 table:
id
param1
param2
config
123
456
789
{"confToUse": "b", "configs": {"a": { "qwe": "rty" }, "b": { "asd", "fgh" } } }
小说明:配置在json 'dictionary' 属性 configs
, configToUse
属性 点在配置上用这个键使用。
我的目标是获得新的 table,其中每一行都是一个单独的配置:
id
name
config
x_uniq
a
{ "qwe": "rty" }
y_uniq
b
{ "asd", "fgh" }
理想情况下,结果如下所示:
id
param1
param2
use
name
config
use_id
x_uniq
456
789
b
a
{ "qwe": "rty" }
y_uniq?
y_uniq
456
789
b
b
{ "asd", "fgh" }
y_uniq?
由于 mysql 版本原因我无法使用 JSON_TABBLE。只有 JSON_EXTRACT 左右。
此时只能这样做:
SELECT
JSON_EXTRACT(tbl.config, "$.configToUse"),
JSON_EXTRACT(tbl.config, "$.configs") -- I think there has to be some SELECT
FROM
configs_table tbl
WHERE
tbl.id = 123
;
并得到:
xxx
yyy
b
{"a": { "qwe": "rty" }, "b": { "asd", "fgh" } }
拜托,给我一些移动方式。
为此,您需要另一个 table(或子查询),它具有从 0 到 N 的整数,其中 N 是您可能拥有的最大配置数量。
为这些整数创建实用程序 table:
CREATE TABLE N ( N INT PRIMARY KEY );
INSERT INTO N (N) VALUES (0), (1), (2), (3), (4), (5);
或者按需生成 table 作为子查询:
SELECT ...
FROM (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS N
...
有了这个,您可以进行交叉连接以获取 JSON 文档中的每个配置键。
这是一个演示:
SELECT
t.param1, t.param2,
JSON_UNQUOTE(JSON_EXTRACT(t.config, '$.confToUse')) AS `use`,
t.name,
JSON_EXTRACT(t.config, CONCAT('$.configs.', t.name)) AS config
FROM (
SELECT c.param1, c.param2, c.config,
JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(c.config->'$.configs'), CONCAT('$[',N.N,']'))) AS name
FROM N CROSS JOIN configs_table c
) AS t
WHERE t.name IS NOT NULL;
输出:
+--------+--------+------+------+----------------+
| param1 | param2 | use | name | config |
+--------+--------+------+------+----------------+
| 456 | 789 | b | a | {"qwe": "rty"} |
| 456 | 789 | b | b | {"asd": "fgh"} |
+--------+--------+------+------+----------------+
我无法从你的问题中得知你是如何获得值 x_uniq
和 y_uniq
,所以我将把那部分解决方案留给你。
如果您认为此解决方案复杂而困难,请将其作为示例,说明为什么在 MySQL 中使用 JSON 会导致很多麻烦和耗时的工作。在数据库之上实现伪数据库既不方便也不正确。这有时称为 Inner-Platform Effect 反模式。
同事们。 我有一个像这样的 table:
id | param1 | param2 | config |
---|---|---|---|
123 | 456 | 789 | {"confToUse": "b", "configs": {"a": { "qwe": "rty" }, "b": { "asd", "fgh" } } } |
小说明:配置在json 'dictionary' 属性 configs
, configToUse
属性 点在配置上用这个键使用。
我的目标是获得新的 table,其中每一行都是一个单独的配置:
id | name | config |
---|---|---|
x_uniq | a | { "qwe": "rty" } |
y_uniq | b | { "asd", "fgh" } |
理想情况下,结果如下所示:
id | param1 | param2 | use | name | config | use_id |
---|---|---|---|---|---|---|
x_uniq | 456 | 789 | b | a | { "qwe": "rty" } |
y_uniq? |
y_uniq | 456 | 789 | b | b | { "asd", "fgh" } |
y_uniq? |
由于 mysql 版本原因我无法使用 JSON_TABBLE。只有 JSON_EXTRACT 左右。
此时只能这样做:
SELECT
JSON_EXTRACT(tbl.config, "$.configToUse"),
JSON_EXTRACT(tbl.config, "$.configs") -- I think there has to be some SELECT
FROM
configs_table tbl
WHERE
tbl.id = 123
;
并得到:
xxx | yyy |
---|---|
b | {"a": { "qwe": "rty" }, "b": { "asd", "fgh" } } |
拜托,给我一些移动方式。
为此,您需要另一个 table(或子查询),它具有从 0 到 N 的整数,其中 N 是您可能拥有的最大配置数量。
为这些整数创建实用程序 table:
CREATE TABLE N ( N INT PRIMARY KEY );
INSERT INTO N (N) VALUES (0), (1), (2), (3), (4), (5);
或者按需生成 table 作为子查询:
SELECT ...
FROM (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS N
...
有了这个,您可以进行交叉连接以获取 JSON 文档中的每个配置键。
这是一个演示:
SELECT
t.param1, t.param2,
JSON_UNQUOTE(JSON_EXTRACT(t.config, '$.confToUse')) AS `use`,
t.name,
JSON_EXTRACT(t.config, CONCAT('$.configs.', t.name)) AS config
FROM (
SELECT c.param1, c.param2, c.config,
JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(c.config->'$.configs'), CONCAT('$[',N.N,']'))) AS name
FROM N CROSS JOIN configs_table c
) AS t
WHERE t.name IS NOT NULL;
输出:
+--------+--------+------+------+----------------+
| param1 | param2 | use | name | config |
+--------+--------+------+------+----------------+
| 456 | 789 | b | a | {"qwe": "rty"} |
| 456 | 789 | b | b | {"asd": "fgh"} |
+--------+--------+------+------+----------------+
我无法从你的问题中得知你是如何获得值 x_uniq
和 y_uniq
,所以我将把那部分解决方案留给你。
如果您认为此解决方案复杂而困难,请将其作为示例,说明为什么在 MySQL 中使用 JSON 会导致很多麻烦和耗时的工作。在数据库之上实现伪数据库既不方便也不正确。这有时称为 Inner-Platform Effect 反模式。