如何重用查询的一部分

时间:2014-04-04 19:30:50

标签: sql hibernate java-ee jpa

我有通过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)

1 个答案:

答案 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