2014-04-04 3 views
0

У меня есть метод Java, который называют Native SQL (Oracle) с помощью Hibernate:Как повторно использовать часть запроса

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 (если параметр недействителен). dist используется в ORDER BY для сортировки результирующего набора.

Эта версия работает должным образом.

Вопрос: Как я могу переписать запрос для повторного использования части dist в ГДЕ?

Цель: исключить 2x расчет distance(ci.coord1, ci.coord2, :latitude, :longitude)

ответ

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 
+0

Отлично. Спасибо @ Серхио. Я только изменил предложение WHERE на 'WHERE NVL (dist,: over) <=: radius'. –

Смежные вопросы