您好,我正在尝试使用Sequelize来执行基于位置的查询,而我却陷入了噩梦!
我正在尝试生成SQL:
SELECT *, (3959 * acos(cos(radians([user-latitude])) * cos(radians(latitude)) * cos(radians(longitude) - radians([user-longitude])) + sin(radians([user-latitude])) * sin(radians(latitude)))) AS distance FROM myModel HAVING distance <= 25 ORDER BY distance ASC LIMIT 0 , 10;
其中[user-latitude]和[user-longitude]是变量。到目前为止,我已经知道了:
myModel.findAll({ attributes: [ '*', [`(3959 * acos(cos(radians(${user-latitude})) * cos(radians(latitude)) * cos(radians(longitude) - radians(${user-longitude})) + sin(radians(${user-latitude})) * sin(radians(latitude))))`, 'distance'], ], where: { distance: { $lte: 25, }, }, order: [ ['distance', 'ASC'], ], limit: 10, offset: 0, });
产生:
SELECT *, (3959 * acos(cos(radians([user-latitude])) * cos(radians(latitude)) * cos(radians(longitude) - radians([user-longitude])) + sin(radians([user-latitude)) * sin(radians(latitude)))) AS `distance` FROM `myModels` AS `myModel` WHERE `myModel`.`distance` <= 15 ORDER BY `myModel`.`distance` ASC LIMIT 0, 10;
这不起作用,因为myModel.distance不是一个字段。有没有一种方法可以在不使用原始查询的情况下完成这项工作?
myModel
distance
很遗憾,您不能在WHERE或HAVING语句中使用别名字段,而只能在中使用ORDER BY。您必须在WHERE子句中重复您的语句,而不要使用别名(就像在Where语句中的SQL Use alias中所说明的那样)。
WHERE
HAVING
ORDER BY
而且,由于distance在where和order属性中使用字段时,Sequelize会自动将其视为myModel而不是your的字段alias,因此会发生您获得的错误,因此您需要按字面意义编写它,因此不会将其视为表的列选择。
where
order
alias
myModel.findAll({ attributes: { include: [[`(3959 * acos(cos(radians(${user-latitude})) * cos(radians(latitude)) * cos(radians(longitude) - radians(${user-longitude})) + sin(radians(${user-latitude})) * sin(radians(latitude))))`, 'distance']] }, where: sequelize.where( sequelize.literal(`(3959 * acos(cos(radians(${user-latitude})) * cos(radians(latitude)) * cos(radians(longitude) - radians(${user-longitude})) + sin(radians(${user-latitude})) * sin(radians(latitude))))`), '<=', 25 ), order: 'distance ASC', limit: 10, offset: 0 });
sequelize 在这种情况下是您的Sequelize实例。
sequelize