这可以作为一个查询来完成,这样就不会有多个请求通过循环向数据库发出?我试图让每个相机的最后一张照片(如果有的话(。
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
let cameras = await knex({ cameras: "device_manager_camera" })
.select()
.where("owner_id", 13);
const start = async () => {
let report = [];
asyncForEach(cameras, async camera => {
let photo = await knex({ photos: "device_manager_photo" })
.where("camera_id", camera.id)
.first();
if (photo) {
report[camera.name] = photo.timestamp;
} else {
report[camera.name] = "never";
}
});
console.log(report);
};
start();
首先,我建议您用纯SQL编写SQL查询,将其转换为knex
命令会容易得多。
至于您的请求,我想出了这个返回[{ camera_id, timestamp }]
数组的查询。它选择ID 为 13 的所有者的摄像机,并将其连接到表 photos
中的最大时间戳分组查询。
select
c.name,
coalesce(t.timestamp::text, 'never') as timestamp
from
cameras as c
left join (
select
p.camera_id,
max(p.timestamp) as timestamp
from
photos as p
group by
camera_id
) as t on t.camera_id = c.id
where
c.owner_id = 13;
如有必要,请更正表名和列。
奖励风格积分。我不建议使用 timestamp
作为列名。它是某些数据库中的保留列,可能需要在它周围加上引号才能在查询中显式将其指定为列,这可能会很烦人。