Sequelize complex aggregate attribute in where and order

倖福魔咒の 提交于 2019-12-11 06:58:47

问题


Hello I'm trying to use Sequelize to perform location based queries, and I'm having a nightmare!

I'm trying to generate the 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;

where [user-latitude] and [user-longitude] are variables. So far I've got this:

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,
});

which generates:

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;

which doesn't work because `myModel`.`distance` is not a field. Is there a way to make this work without using raw queries?


回答1:


Unfortunately you cannot use alias field in the WHERE or HAVING statement, only in the ORDER BY. You must repeat your statement in the WHERE clause instead using alias (just as it is explained in SQL Use alias in Where statement).

What is more, the error you obtained happens because when you used field distance in the where and order attributes, Sequelize automatically treated it as a field of myModel instead your alias, so you need to write it literally so it won't be treated as a column of table you select.

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 in this case is your instance of Sequelize.



来源:https://stackoverflow.com/questions/42634043/sequelize-complex-aggregate-attribute-in-where-and-order

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!