您好,我正在尝试使用 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` 不是一个字段。有没有办法在不使用原始查询的情况下完成这项工作?
最佳答案
不幸的是,您不能在 WHERE
或 HAVING
语句中使用 alias 字段,只能在 ORDER BY
中使用。您必须在 WHERE
子句中重复您的语句,而不是使用别名(就像在 SQL Use alias in Where statement 中解释的那样)。
更重要的是,您获得的错误发生是因为当您在 distance
和 where
属性中使用字段 order
时,Sequelize 自动将其视为 myModel
的字段而不是您的 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 实例。
关于sql - 按位置和顺序对复杂的聚合属性进行 Sequelize ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42634043/