我有通过Hibernate调用Native SQL(Oracle)的Java方法:
public List<Location> getLocationsAround(double latitude, double longitude, double radius, long retailerId) {
List<Location> locationList = (List<Location>) SessionManager.getSession().createSQLQuery(
"SELECT loc.*, distance(ci.coord1, ci.coord2, :latitude, :longitude) as dist " +
"FROM location loc " +
"join rl_retailer_location rrl on rrl.location_id = loc.location_id " +
"join contact_info ci on ci.contact_info_id=loc.contact_info_id " +
"WHERE rrl.retailer_id=:retailerId " +
"and NVL(distance(ci.coord1, ci.coord2, :latitude, :longitude), :limit) <= :radius " +
"ORDER BY dist ASC"
).addEntity("loc", DAO.getInstance().getMappedClass(Location.class))
.setLong("retailerId", retailerId)
.setDouble("latitude", latitude)
.setDouble("longitude", longitude)
.setDouble("radius", radius)
.setDouble("limit", radius + 1.)
.list();
return locationList;
}
对于dist
计算,使用FUNCTION(存储过程)distance
,它有4个参数(数字):latitude1,longitude1,latitude2,longitude2并返回NUMBER(18,6)或null(如果参数)无效)。在ORDER BY中使用dist
进行结果集排序。
此版本按预期工作。
问题:如何在WHERE中重写部分dist
的查询?
目标:消除2x计算distance(ci.coord1, ci.coord2, :latitude, :longitude)
答案 0 :(得分:2)
在Oracle中,您可以在FROM
子句中使用查询作为表格,这样您就可以执行以下操作:
SELECT *
FROM (
SELECT loc.*
, distance(ci.coord1, ci.coord2, :latitude, :longitude) as dist
FROM location loc
JOIN rl_retailer_location rrl on rrl.location_id = loc.location_id
JOIN contact_info ci on ci.contact_info_id=loc.contact_info_id
WHERE rrl.retailer_id=:retailerId
) loc
WHERE dist <= :radius
ORDER BY dist ASC