我有两张table:Files
和FileLogs
,我试图摆脱FileLogs
表,并将其中的一些数据存储在Files
表中。
文件
| 身份证|lastStatusId| meta|
| --------------|--------------|--------------|
| 一百八十七|一百零一|空|
| 一八八|一百零一|{“foo”:“bar”}|
文件日志
| 身份证|文件ID|状态Id|创建时间| meta|
| --------------|--------------|--------------|--------------|--------------|
| 1|一百八十七|一百零一|2019-06-18 19:43:19|空|
| 第二章|一百八十七|一百零二|2019-06-18 19:43:22|空|
| 三|一百八十七|二百零二|2019-06-18 19:45:32|{“foo2”:“bar2”}|
我已经将lastStatusId
列添加到Files表中(默认值为101)。
为了从日志中获取每个文件的最新statusId
到latestStatusId
,我运行了这个查询,它工作得很好:
UPDATE
`Files` f1,
(
SELECT
f.id as fileId,
fl.statusId,
fl.meta
FROM
(
SELECT
MAX(id) as id,
fileId
FROM
`FileLogs`
GROUP BY
fileId
) AS latestIds
LEFT JOIN `FileLogs` AS fl ON latestIds.id = fl.id
LEFT JOIN `Files` AS f ON f.id = fl.fileId
ORDER BY
fl.id ASC
) temp1
SET
f1.lastStatusId = temp1.statusId
WHERE
f1.id = temp1.fileId;
我想我可以使用一个类似的查询来检查所有FileLogs并将状态写入Files的meta
字段,如下所示:
UPDATE
`Files` f1,
(
SELECT
f.id as fileId,
fl.statusId,
fl.meta,
fl.createdAt
FROM
`FileLogs` AS fl
LEFT JOIN `Files` AS f ON f.id = fl.fileId
) temp1
SET
f1.meta = JSON_MERGE_PATCH(
COALESCE(f1.meta, '{}'),
JSON_OBJECT(
'statusInfo',
JSON_OBJECT(
CONCAT('', temp1.`statusId`),
JSON_OBJECT(
'createdAt',
temp1.createdAt
)
)
)
)
WHERE
f1.id = temp1.fileId;
子查询的结果如下所示:
fileId statusId meta createdAt
187 101 NULL 2019-06-18 19:43:19
187 102 NULL 2019-06-18 19:43:22
187 202 {"foo": "bar"} 2019-06-18 19:43:26
但是SET只对第一个f1.id = temp1.fileId
运行,而不是第二个或第三个(这是有道理的)-结果看起来像这样:
File id:187
meta
{
"statusInfo": {
"101": {
"createdAt": "2019-06-18 19:43:19.000000"
}
}
}
1.我怎样才能实现另外两个状态(102,202)也被添加到 meta列?
1.我如何也能在那里获得FileLogs的 meta数据(如果不是null)?
1条答案
按热度按时间ig9co6j11#
您可以在子查询中预先聚合JSON。下面是一个演示:
给出示例数据的结果:
现在,这类似于你想要的JSON结构,我们可以将其 Package 到UPDATE中:
但是,您应该考虑这样做的影响。
FileLogs
的行中存储相同的数据占用更多的空间。File.meta
JSON文档添加后续信息可以通过JSON合并来完成,但这肯定比简单地向FileLogs
插入一个新行需要更仔细的考虑。FileLogs
的行中,则会简单得多。在使用JSON之前,你应该确保你知道如何做所有你需要做的查询。