我没有主意了。我在谷歌上搜索了一天多,仍然找不到任何有用的答案来回答我的问题。
到目前为止,我一直尝试使用原始sql,但运气不佳。
locations = db.session.query(Location, select([text('( 6371 * acos( cos( radians("53.6209798282177") ) * cos( radians( lat ) ) * cos( radians( lng ) - radians("13.96948162900808") ) + sin( radians("53.6209798282177") ) * sin( radians( lat ) ) ) )')]).label('distance')).having('distance' < 25).all()
使用此原始sql查询时,返回的结果为零,但在中运行相同的查询时 mysql
它返回正确的结果。
我进一步发现,当将查询打印到终端时,它不会处理 HAVING()
从句正确。
打印时,我的查询如下所示:
SELECT location.id AS location_id, location.created_date AS location_created_date, location.zip AS location_zip, location.user_id AS location_user_id, location.lat AS location_lat, location.lng AS location_lng, location.city AS location_city
FROM location
HAVING false = 1
如何将此sql查询转换为sqlalchemy
SELECT *, ( 6371 * acos( cos( radians(53.6209798282177) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(11.96948162900808) ) + sin( radians(53.6209798282177) ) * sin( radians( lat ) ) ) ) AS distance FROM location HAVING distance < 25 ORDER BY distance;
我的table是这样的:
+--------------+----------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+----------------+------+-----+---------+-------+
| id | varchar(50) | NO | PRI | NULL | |
| created_date | datetime | YES | | NULL | |
| zip | varchar(5) | NO | UNI | NULL | |
| user_id | varchar(50) | NO | | NULL | |
| lat | decimal(15,13) | NO | | NULL | |
| lng | decimal(15,13) | NO | | NULL | |
| city | text | NO | | NULL | |
+--------------+----------------+------+-----+---------+-------+
感谢您的帮助。
1条答案
按热度按时间wnvonmuf1#
你的
HAVING
处理正确,但传递的表达式错误。似乎您使用的是python2,因为字符串和整数之间的关系比较不引发异常,但计算结果为
False
相反。换句话说,您的查询等于这就解释了为什么结果为零:所有行都被having子句显式过滤掉,如打印版本所示:
解决方法是使用合适的构造,例如
column()
,生成表达式:不应该将复杂的select列表项表达式 Package 在
select()
,它表示select语句。要么给text()
原样:或使用模型构建表达式:
您可以通过为大圆距离生成一个函数来提高查询构造的可读性,并且只需做一点工作,就可以在上实现一个混合方法
Location
:请注意,消除非组行的方法是不可移植的。例如,在postgresql中,having子句的存在将查询转换为分组查询,即使没有groupby子句。您可以改用子查询: