2013-06-15 5 views
0

Как я могу использовать этот запрос в CDbCriteria формате >>Yii CDbCriteria - SQL - Как заявление

SET @orig_lat=122.4058; 

SET @orig_lon=37.7907; 

SET @dist=10; 

SELECT * 
    , 3956 
    * 2 
    * ASIN(SQRT(POWER(SIN((@orig_lat - abs(dest.latitude)) * pi()/180/2),2) + COS(@orig_lat * pi()/180) * COS(ABS (dest.latitude) * pi()/180) * POWER(SIN((dest.longitude - @orig_lon) * pi()/180/2), 2))) distance 
    FROM business 
HAVING distance < @dist 
ORDER 
    BY distance 
LIMIT 10; 

Кто-то спросил его here. , но я не получаю ответа.

+0

Можете ли вы дать некоторый контекст на свой вопрос? Что у вас есть и какой результат вам нужен? Может быть, кто-то может предложить альтернативный путь. –

ответ

0

Рассмотреть вопрос, что формула «Haversine» в функции MySQL, чтобы начать с:

CREATE FUNCTION `HAVERSINE`(origin_lat FLOAT, origin_long FLOAT, dest_lat FLOAT, dest_long FLOAT) 
RETURNS float 
DETERMINISTIC 
BEGIN 
    DECLARE R FLOAT; 
    SET R = 3956 * 2 * ASIN(SQRT(POWER(SIN((origin_lat - dest_lat) * pi()/180/2), 2) + COS(origin_lat * pi()/180) * COS(dest_lat * pi()/180) * POWER(SIN((origin_long-dest_long) * pi()/180/2), 2))) * 1.609344; 
    RETURN R; 
END; 

Таким образом, вы можете вызвать его в своих запросах.

И затем вы можете абстрагироваться дальше, создав хранимую процедуру для получения ближайших предприятий. Что-то вроде:

CREATE PROCEDURE `findClosestBusinessesToLatLng`(lat FLOAT, lng FLOAT) 
BEGIN 
    SELECT *, HAVERSINE(lat, lng, businesses.lat, businesses.lng) AS dist 
    FROM  businesses 
    ORDER BY dist 
END 

Тогда ваш запрос становится просто

Call(findClosestBusinessesToLatLng(122.4058,37.7907)); 
+0

Благодарю вас за ответы, и задайте вопрос, чтобы задать вопрос не так ... , но есть ли способ использовать CDBCriteria в методе? – user1710202

+0

@ user1710202 Какова ваша цель в использовании CDBCriteria? Если вам просто нужен массив моделей ActiveRecord, почему бы не использовать приведенное выше в методе model :: findAllBySql(). –

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