У меня есть модель Supplier
с соответствующими моделями Calendar
.
Я хочу получить поставщиков, которые либо
- есть календарь, который доступен
- нет календаря
Я могу сделать это, используя следующее:
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 },
],
},
},
});
Это генерирует следующий SQL (ненужные столбцы удалены):
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"
;
Круто, как и ожидалось. Что будет, если я добавлю limit
? * 1020 Т.е. *
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,
});
Это производит следующее:
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"
Это совершенно другой запрос, основная часть которого помещена в подзапрос, а объединение размещено снаружи. Но условие where
в объединенной таблице помещается в подзапрос до того, как произошло соединение, и поэтому не выполняется.
Какой правильный подход здесь?