使用 Sequelize 模型续集 Op.notIn
Sequelize Op.notIn with Sequelize Model
你好,我有一个 mysql 查询,它在 sequelize.query 中运行良好,查询是
select list_name from lists l where l.list_id not in
(SELECT sub.list_id from list_sub_activities sub left join.
Activities a on a.list_act_id = sub.list_act_id where a.agency_id = 2)
我想使用续集模型做同样的事情,我已经尝试过了,但我想我遗漏了一些东西。
包列表 ---> 列表
List_of_Packages.findAll({
attributes: ['list_name'],
where: {
list_id: {
[Op.notIn]: [List_sub_Activities.findAll({
attributes: ['list_id'],
include: {
model: Activities,
required: false,
where: {
agency_id: 2
}
}
})
]
}
}
}).then((response) => {
console.log(response);
})
如果你能帮助我,我将不胜感激。
谢谢!!!
findAll()
(和其他查询方法)是异步的,因此在将 list_id
传递给 Op.notIn
。它还将 return 一个 对象数组 和一个 属性 的 list_id
,所以你需要在你之前将它映射到一个整数数组可以使用它。您还可以传入 raw: true
,这样它就不会从您的结果中生成 Sequelize 实例,而是 return 普通 javascript 对象——这比创建对象只是为了获取单个 属性.
通过在 Activities
包含上设置 required: false
,您将 returning 所有 List_sub_Activities
而不是过滤它们(有些在您的结果中将为空)。这可能不是您想要的。
为清楚起见,此示例使用 async/await
而不是 thenables
。请注意,这 不是 最有效,因为它需要多个数据库查询,理想的解决方案是使用 LEFT JOIN
然后删除 package.list_id IS NULL
(见第二个例子)。
// get an array of Activities with the list_id set
const activities = await List_sub_Activities.findAll({
attributes: ['list_id'],
include: {
model: Activities,
// don't use required: false to only return results where List_sub_Activities.Activities is not null
// required: false,
where: {
agency_id: 2,
},
},
raw: true,
});
// map the property to an array of just the IDs
const activityIds = activities.map((activity) => activity.list_id);
// now you can pass the activityIds to Op.notIn
const packages = await List_of_Packages.findAll({
attributes: ['list_name'],
where: {
list_id: {
[Op.notIn]: activityIds,
},
},
});
有了 thenables。
List_sub_Activities.findAll(...)
.then((activities) => activities.map((activity) => activity.list_id))
.then((activityIds) => List_of_Packages.findAll(...))
.then((packages) => {
console.log(packages);
});
这个例子左连接 List_of_Packages
到 List_sub_Activities
连接到 Activities
并且 WHERE 将 agency_id
设置为 2,然后只有 returns来自 List_of_Packages
的结果,其中 List_sub_Activities.list_id
是 NULL
(在 LEFT JOIN 上没有匹配)。这应该 return 在单个查询中得到与上面相同的结果。
// Get List_of_Packages where there is no match in List_sub_Activities after
// it is joined to Activities with the agency_id set.
const agencyId = 2;
const packages = await List_of_Packages.findAll({
attributes: ['list_name'],
include: {
model: List_sub_Activities,
// we don't need to actually fetch the list_id
attributes: [],
include: {
model: Activities,
where: {
agency_id: agencyId,
},
},
// uses a LEFT JOIN
required: false,
},
// only return results where the List_sub_Activities.list_id is null
where: sequelize.where(sequelize.col('List_sub_Activities.list_id'), 'IS', null),
});
你好,我有一个 mysql 查询,它在 sequelize.query 中运行良好,查询是
select list_name from lists l where l.list_id not in
(SELECT sub.list_id from list_sub_activities sub left join.
Activities a on a.list_act_id = sub.list_act_id where a.agency_id = 2)
我想使用续集模型做同样的事情,我已经尝试过了,但我想我遗漏了一些东西。
包列表 ---> 列表
List_of_Packages.findAll({
attributes: ['list_name'],
where: {
list_id: {
[Op.notIn]: [List_sub_Activities.findAll({
attributes: ['list_id'],
include: {
model: Activities,
required: false,
where: {
agency_id: 2
}
}
})
]
}
}
}).then((response) => {
console.log(response);
})
如果你能帮助我,我将不胜感激。
谢谢!!!
findAll()
(和其他查询方法)是异步的,因此在将 list_id
传递给 Op.notIn
。它还将 return 一个 对象数组 和一个 属性 的 list_id
,所以你需要在你之前将它映射到一个整数数组可以使用它。您还可以传入 raw: true
,这样它就不会从您的结果中生成 Sequelize 实例,而是 return 普通 javascript 对象——这比创建对象只是为了获取单个 属性.
通过在 Activities
包含上设置 required: false
,您将 returning 所有 List_sub_Activities
而不是过滤它们(有些在您的结果中将为空)。这可能不是您想要的。
为清楚起见,此示例使用 async/await
而不是 thenables
。请注意,这 不是 最有效,因为它需要多个数据库查询,理想的解决方案是使用 LEFT JOIN
然后删除 package.list_id IS NULL
(见第二个例子)。
// get an array of Activities with the list_id set
const activities = await List_sub_Activities.findAll({
attributes: ['list_id'],
include: {
model: Activities,
// don't use required: false to only return results where List_sub_Activities.Activities is not null
// required: false,
where: {
agency_id: 2,
},
},
raw: true,
});
// map the property to an array of just the IDs
const activityIds = activities.map((activity) => activity.list_id);
// now you can pass the activityIds to Op.notIn
const packages = await List_of_Packages.findAll({
attributes: ['list_name'],
where: {
list_id: {
[Op.notIn]: activityIds,
},
},
});
有了 thenables。
List_sub_Activities.findAll(...)
.then((activities) => activities.map((activity) => activity.list_id))
.then((activityIds) => List_of_Packages.findAll(...))
.then((packages) => {
console.log(packages);
});
这个例子左连接 List_of_Packages
到 List_sub_Activities
连接到 Activities
并且 WHERE 将 agency_id
设置为 2,然后只有 returns来自 List_of_Packages
的结果,其中 List_sub_Activities.list_id
是 NULL
(在 LEFT JOIN 上没有匹配)。这应该 return 在单个查询中得到与上面相同的结果。
// Get List_of_Packages where there is no match in List_sub_Activities after
// it is joined to Activities with the agency_id set.
const agencyId = 2;
const packages = await List_of_Packages.findAll({
attributes: ['list_name'],
include: {
model: List_sub_Activities,
// we don't need to actually fetch the list_id
attributes: [],
include: {
model: Activities,
where: {
agency_id: agencyId,
},
},
// uses a LEFT JOIN
required: false,
},
// only return results where the List_sub_Activities.list_id is null
where: sequelize.where(sequelize.col('List_sub_Activities.list_id'), 'IS', null),
});