问题描述
我在 MariaDB 15.1 中使用 JSON_ARRAYAGG
时有两个问题
省略了括号 []
不正确的错误结果,值重复或省略
我的数据库如下:
用户:
+----+------+
| id | name |
+----+------+
| 1 | Jhon |
| 2 | Bob |
+----+------+
汽车:
+----+---------+-------------+
| id | user_id | model |
+----+---------+-------------+
| 1 | 1 | Tesla |
| 2 | 1 | Ferrari |
| 3 | 2 | Lamborghini |
+----+---------+-------------+
电话:
+----+---------+----------+--------+
| id | user_id | company | number |
+----+---------+----------+--------+
| 1 | 1 | Verzion | 1 |
| 2 | 1 | AT&T | 2 |
| 3 | 1 | T-Mobile | 3 |
| 4 | 2 | Sprint | 4 |
| 5 | 1 | Sprint | 2 |
+----+---------+----------+--------+
1。省略括号 []
SELECT
user.id AS id,user.name AS name,JSON_ARRAYAGG(
JSON_OBJECT(
'id',car.id,'model',car.model
)
) AS cars
FROM user
INNER JOIN car ON user.id = car.user_id
GROUP BY user.id;
结果:[]
中省略了方括号 cars
(JSON_ARRAYAGG
的行为类似于 GROUP_CONCAT
)
+----+------+-----------------------------------------------------------+
| id | name | cars |
+----+------+-----------------------------------------------------------+
| 1 | Jhon | {"id": 1,"model": "Tesla"},{"id": 2,"model": "Ferrari"} |
| 2 | Bob | {"id": 3,"model": "Lamborghini"} |
+----+------+-----------------------------------------------------------+
但是当添加过滤器 WHERE user.id = 1
时,括号 []
不会被省略:
+----+------+-------------------------------------------------------------+
| id | name | cars |
+----+------+-------------------------------------------------------------+
| 1 | Jhon | [{"id": 1,"model": "Ferrari"}] |
+----+------+-------------------------------------------------------------+
2.不正确的错误结果,值重复或省略
这个错误很奇怪,因为必须满足以下条件:
重复值
SELECT
user.id AS id,JSON_ARRAYAGG( disTINCT
JSON_OBJECT(
'id',car.model
)
) AS cars,JSON_ARRAYAGG( disTINCT
JSON_OBJECT(
'id',phone.id,'company',phone.company,'number',phone.number
)
) AS phones
FROM user
INNER JOIN car ON user.id = car.user_id
INNER JOIN phone ON user.id = phone.user_id
GROUP BY user.id;
我会将输出保留为 json 格式,只保留感兴趣的元素。
结果:括号[]
被省略并重复Verizon
{
"id": 1,"name": "Jhon","phones": // [ opening bracket expected
{
"id": 5,"company": "Sprint","number": 2
},{
"id": 1,"company": "Verzion","number": 1
},// Duplicate object with the disTINCT option
{
"id": 2,"company": "AT&T",{
"id": 3,"company": "T-Mobile","number": 3
}
// ] Closing bracket expected
}
省略的值
SELECT
user.id AS id,JSON_ARRAYAGG( disTINCT
JSON_OBJECT(
--'id',phone.number
)
) AS phones
FROM user
INNER JOIN car ON user.id = car.user_id
INNER JOIN phone ON user.id = phone.user_id
GROUP BY user.id;
结果:括号[]
被省略,Sprint
被省略。
显然这是因为它在 JSON_OBJECT
的列之间创建了 OR 类型,因为 company
存在于不同的行中,而 number
存在于另一个不同的行中
{
"id": 1,"phones": // [ opening bracket expected
//{
// "company": "Sprint",// "number": 2
//},`Sprint` was omitted
{
"company": "Verzion",{
"company": "AT&T",{
"company": "T-Mobile","number": 3
}
// ] Closing bracket expected
}
GROUP_CONCAT
JSON_ARRAYAGG
实例解决了 duplicate
或 omitted
对象的问题
但是,通过添加过滤器WHERE user.id = 1
,方括号[]
不会被省略,也解决了duplicate
或omitted
对象的问题:
{
"id": 1,"phones": [
{
"id": 1,{
"id": 2,"number": 3
},{
"id": 5,"number": 2
}
]
}
我做错了什么?
解决方法
到目前为止,我的解决方案是这样,但我想使用 JSON_ARRAYAGG,因为查询更清晰
-- 1
SELECT
user.id AS id,user.name AS name,CONCAT(
'[',GROUP_CONCAT( DISTINCT
JSON_OBJECT(
'id',car.id,'model',car.model
)
),']'
) AS cars
FROM user
INNER JOIN car ON user.id = car.user_id
GROUP BY user.id;
-- 2
SELECT
user.id AS id,']'
) AS cars,GROUP_CONCAT( DISTINCT
JSON_OBJECT(
'id',phone.id,'company',phone.company,'number',phone.number
)
),']'
) AS phones
FROM user
INNER JOIN car ON user.id = car.user_id
INNER JOIN phone ON user.id = phone.user_id
GROUP BY user.id;