问题
I have a Supplier
model with associated Calendar
models.
I want to fetch suppliers who either
- have a calendar which is set to available
- don't have a calendar
I can do this using the following:
Supplier.findAll({
include: [
{
model: Calendar,
as: 'calendars',
required: false,
where: {
start_time: { [Op.lte]: date },
end_time: { [Op.gte]: date },
},
},
],
where: {
'$calendars.state$': {
[Op.or]: [
{ [Op.in]: ['available'] },
{ [Op.eq]: null },
],
},
},
});
This generates the following SQL (irrelevant columns removed):
SELECT
"suppliers"."uuid"
,"calendars"."uuid" AS "calendars.uuid"
,"calendars"."state" AS "calendars.state"
FROM "suppliers" AS "suppliers"
LEFT OUTER JOIN "suppliers_calendars" AS "calendars" ON
"suppliers"."uuid" = "calendars"."supplier_id"
AND "calendars"."start_time" <= '2019-05-27 23:00:00.000 +00:00'
AND "calendars"."end_time" >= '2019-05-27 23:00:00.000 +00:00'
WHERE (
("calendars"."state" IN ('available')
OR "calendars"."state" IS NULL
)
)
ORDER BY "suppliers"."uuid"
;
Cool, as expected. Now what happens if I add a limit
? I.e.
Supplier.findAll({
include: [
{
model: Calendar,
as: 'calendars',
required: false,
where: {
start_time: { [Op.lte]: date },
end_time: { [Op.gte]: date },
},
},
],
where: {
'$calendars.state$': {
[Op.or]: [
{ [Op.in]: ['available'] },
{ [Op.eq]: null },
],
},
},
limit: 10,
});
This produces the following:
SELECT
"suppliers".*
,"calendars"."uuid" AS "calendars.uuid"
,"calendars"."state" AS "calendars.state"
FROM (
SELECT "suppliers"."uuid"
FROM "suppliers" AS "suppliers"
WHERE (
("calendars"."state" IN ('available')
OR "calendars"."state" IS NULL)
)
ORDER BY "suppliers"."uuid"
LIMIT 10
) AS "suppliers"
LEFT OUTER JOIN "suppliers_calendars" AS "calendars" ON
"suppliers"."uuid" = "calendars"."supplier_id"
AND "calendars"."start_time" <= '2019-05-27 23:00:00.000 +00:00'
AND "calendars"."end_time" >= '2019-05-27 23:00:00.000 +00:00'
ORDER BY "suppliers"."uuid"
This is a completely different query, with the main part put into a subquery and the join placed outside. But the where
condition on the joined table is put inside the subquery, before the join has occurred, and so fails.
What is the correct approach here?
来源:https://stackoverflow.com/questions/56171187/sequelize-condition-on-joined-table-doesnt-work-with-limit-condition