我一直在整个下午尝试使用诸如findOne()之类的Sequelize模型方法来表达以下SQL查询。
SELECT * FROM "Tariffs" WHERE "tariffType" = 'DateRange' AND (('${body.startDate}' BETWEEN "startDate" AND "endDate") OR ('${body.endDate}' BETWEEN "startDate" AND "endDate")) LIMIT 1
其中body.startDate
和body.endDate
由HTTP帖子提供-startDate
和endDate
是PostgreSQL后端中保存的日期列。
很明显,我可以直接使用query()
执行此操作,但这违背了首先使用ORM的目的。
提供给findOne()
的对象的标准似乎并没有提供一种明显的方式来提供与之匹配的文字值,并且总是期望列名和 then 一个值。但是有一种sequelize.where()
方法可以使您在某种程度上解决这个问题,而我能想到的最好的就是这种怪诞-
Tariffs.findOne({
where: {
[Op.and]: [{
tariffType: "DateRange"
},
{
[Op.or]: [sequelize.where(sequelize.literal(`'${body.startDate}'`), Op.between, sequelize.literal('"startDate" AND "endDate"')),
sequelize.where(sequelize.literal(`'${body.endDate}'`), Op.between, sequelize.literal('"startDate" AND "endDate"'))
]
}
]
}
});
这大量使用了sequelize.literal
,这可能也是不希望的-我尝试使用sequelize.col
在where()
调用中定义列名,但是该方法似乎不想解释它们作为列名。
有人可以建议一种更好的方法吗?还是我不得不坚持运行原始查询?
编辑13/05/20
分析的答案是正确的-谢谢。
但是,我原来的逻辑是错误的-我实际上想将记录的开始和结束日期在提供的开始和结束日期之内,以及提供的开始日期在其范围内或提供的结束日期在其范围内的记录进行匹配范围。因此,[Op.or]
运算符之后需要一个额外的对象-
[Op.or]: [{
startDate: {
[Op.lte]: body.startDate
},
endDate: {
[Op.gte]: body.startDate
} }, {
startDate: {
[Op.lte]: body.endDate
},
endDate: {
[Op.gte]: body.endDate
} }, {
startDate: {
[Op.gte]: body.startDate
},
endDate: {
[Op.lte]: body.endDate
}
}]
答案 0 :(得分:0)
您可以尝试以下操作:
allAddresses.setValue(response.body());