2

我目前有一个结构如下的表:

customer_id  name   phoneNumbers  
1            Adam   [{'type':'home','number':'687-5309'} , {'type':'cell','number':'123-4567'}] 
2            Bill   [{'type':'home','number':'987-6543'}] 

将 phoneNumbers 列设置为 JSON 列类型。为简单起见,尽管我想将所有 JSON 电话号码转换为一个新的单独表。就像是:

phone_id  customer_id type    number
1         1           home    687-5309  
2         1           cell    123-4567
3         2           home    987-6543

似乎它应该可以使用 OPENJSON,但到目前为止,我还没有弄清楚如何正确声明它的运气。任何帮助表示赞赏。

4

3 回答 3

1

你可以这样做:

SELECT id,
    name,
    JSON_UNQUOTE(JSON_EXTRACT(phone, CONCAT("$[", seq.i, "]", ".", "number"))) AS NUMBER, 
    JSON_UNQUOTE(JSON_EXTRACT(phone, CONCAT("$[", seq.i, "]", ".", "type"))) AS TYPE
FROM customer, (SELECT 0 AS I UNION ALL SELECT 1) AS seq
WHERE seq.i < json_length(phone)

诀窍是(SELECT 0 as i union all SELECT 1),取决于您的 JSON 数组的长度,您可能需要添加更多索引。您可以通过以下方式找出最大长度:

SELECT MAX(JSON_LENGTH(phone)) FROM customer;
于 2018-08-21T09:03:40.607 回答
1

使用 1 的递归 CTE 并递归到 json_length。

SELECT c.*, JSON_LENGTH(c.phoneNumbers) as json_length
from customers c;

然后使用 concat 在 Extract Query 中传递该 element_id:

(json_unquote(JSON_EXTRACT(phoneNumbers, CONCAT('$.type.',1))), json_unquote(JSON_EXTRACT(phoneNumbers, CONCAT('$.number.',1))))
(json_unquote(JSON_EXTRACT(phoneNumbers, CONCAT('$.type.',2))), json_unquote(JSON_EXTRACT(phoneNumbers, CONCAT('$.number.',1))))
-
-
-
(json_unquote(JSON_EXTRACT(phoneNumbers, CONCAT('$.type.',json_length))), json_unquote(JSON_EXTRACT(phoneNumbers, CONCAT('$.number.',json_length))))
于 2018-08-21T04:44:47.270 回答
0

请根据 MySQL\Maria 版本更改 CTE 定义语法。

WITH RECURSIVE cte_recurse_json AS
(
  SELECT customer_id, phone_numbers, 0 as recurse, JSON_LENGTH(c.phoneNumbers) as json_length, 
            json_unquote(JSON_EXTRACT(phoneNumbers, CONCAT('$[',0,'].type'))) as type, 
            json_unquote(JSON_EXTRACT(phoneNumbers, CONCAT('$[',0,'].number'))) as number
  FROM table
  UNION ALL
  SELECT t.customer_id, t.phone_numbers, ct.recurse + 1 as recurse, t.json_length, 
            json_unquote(JSON_EXTRACT(ct.phoneNumbers, CONCAT('$[',ct.recurse,'].type'))) as type, 
            json_unquote(JSON_EXTRACT(ct.phoneNumbers, CONCAT('$[',ct.recurse,'].number'))) as number
  FROM TABLE t
  INNER JOIN cte_recurse_json ct ON t.customer_id = ct.customer_id
  WHERE ct.recurse < json_length
)
SELECT customer_id, type, number FROM cte_recurse_json;
于 2018-08-22T05:34:13.170 回答