在MySQL 8.0中引入了json_arrayagg,这使得聚合json结果成为可能。
现在我想用它来显示附加到邮件的标签。
目前有三个表(简单)
CREATE TABLE IF NOT EXISTS feed_message (
id CHAR(36) PRIMARY KEY
);
CREATE TABLE IF NOT EXISTS feed_tag (
id CHAR(36) PRIMARY KEY,
name VARCHAR(30) NOT NULL
);
CREATE TABLE IF NOT EXISTS feed_message_tag (
message CHAR(36) NOT NULL,
tag CHAR(36) NOT NULL,
PRIMARY KEY (message, tag)
);
因此,有一个表包含消息,一个包含所有标记,一个表包含标记和消息之间的连接(feed_message_tag)。
我正在寻找的响应是一个带有一列标签的消息列表,这些标签是一个带有id + name的对象数组。所以接下来的事情
[{"id": 1, "name": "Foo"}]
现在我发现的示例使用(内部)连接,这意味着消息必须具有标记,但并非总是如此,因此使用了左连接。这让我想到了以下使用的查询
SELECT
json_arrayagg(
json_object(
'id',
ft.id,
'name',
ft.name
)
) as 'tags'
FROM feed_message fm
LEFT JOIN feed_message_tag fmt ON fmt.message = fm.id
LEFT JOIN feed_tag ft ON fmt.tag = ft.id
GROUP BY fm.id
现在的问题是,如果一条消息没有标签,我会得到以下输出tags
。
[{"id": null, "name": null}]
经过一些搜索和调整后,我对tags
列进行了以下更改
IF(
fmt.message IS NULL,
json_array(),
json_arrayagg(
json_object(
'id',
ft.id,
'name',
ft.name
)
)
) as 'tags'
这是预期的行为还是我做错了什么?
答案 0 :(得分:0)
似乎你的方法可能是唯一的方法。
原因是NULL
是包含在JSON对象中的有效值。虽然大多数聚合函数都忽略空值,但它们正确地忽略来自LEFT JOIN
的不匹配行,这对JSON_ARRAYAGG()
来说是个问题。它会阻止您在其他情况下包含空值。没有办法将显式空值与LEFT JOIN
空值区分开来。