Hello i have a mysql query which is working fine in sequelize.query and the query is
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)
and i want to do the same using the sequelize model, i have tried but i think i am missing something.
List of Package ---> lists
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); })
I appreciate that if you help me.
Thank you !!!
The findAll()
(and other query methods) are asynchronous so you will need to resolve the promise (or use a callback) to resolve the value before you can pass the list_id
s to Op.notIn
. It will also return an array of objects with a property of list_id
, so you will need to map this to an array of integers before you can use it. You can also pass in raw: true
so that it will not generate Sequelize Instances from your results and will instead return plain javascript objects - this is more efficient than creating objects just to fetch a single property.
By setting required: false
on the Activities
include you will be returning all List_sub_Activities
and not filtering on them (some will be null in your results). This is likely not what you intended.
This example uses async/await
for clarity instead of thenables
. Note that this is not the most efficient as it requires multiple database queries, the ideal solution would be to use a LEFT JOIN
and then remove items where the package.list_id IS NULL
(see second example).
// 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,
},
},
});
With thenables.
List_sub_Activities.findAll(...)
.then((activities) => activities.map((activity) => activity.list_id))
.then((activityIds) => List_of_Packages.findAll(...))
.then((packages) => {
console.log(packages);
});
This example LEFT JOINs List_of_Packages
to List_sub_Activities
which is JOINed to Activities
with a WHERE setting the agency_id
to 2, then only returns results from List_of_Packages
where the List_sub_Activities.list_id
is NULL
(nothing was matched on the LEFT JOIN). This should return the same results as above in a single query.
// 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),
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.