2011-05-26 265 views
3

我有一個存儲過程,它根據用戶可以選擇多個要搜索的位置的事實來查找用戶的首選項。因此,對於每個位置,查詢都需要查找結果該地區。目前,該過程只返回1個結果。另外,我希望能夠實施某種排名系統,以便將結果排序爲一個組合Feed。我意識到,如果我使用的是一個while循環,它將按位置對結果進行分組,這是我不想要的。重構此過程的最佳方法是什麼,以便3個查詢的結果是網狀的,並允許我靈活地對結果進行排序?結合MySQL存儲過程的結果

DELIMITER $$ 

    DROP PROCEDURE IF EXISTS `geodist` $$ 
    CREATE PROCEDURE geodist (IN userid INT) BEGIN 
    DECLARE mylon DOUBLE; DECLARE mylat DOUBLE; 
    DECLARE lon1 FLOAT; DECLARE lon2 FLOAT; 
    DECLARE lat1 FLOAT; DECLARE lat2 FLOAT; 
    DECLARE dist INT; 
    DECLARE no_more_locations INT; DECLARE l_location_count INT; 

    -- get the original lon and lat for the userid 
    DECLARE location_cursor CURSOR FOR 
     SELECT geo_lat, geo_long, distance 
     FROM activity_location_preferences 
     INNER JOIN activity_preferences ON activity_location_preferences.preference_id = activity_preferences.id 
     WHERE activity_preferences.user_id = userid 
     ORDER BY activity_preferences.id ASC 
     LIMIT 3; 

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_locations = 1; 

    SET no_more_locations = 0; 
    OPEN location_cursor; 
    location_loop:WHILE(no_more_locations = 0) DO 
     FETCH location_cursor INTO mylat, mylon, dist; 
     IF no_more_locations = 1 THEN 
      LEAVE location_loop; 
     END IF; 
     SET l_location_count = l_location_count+1; 

     -- calculate lon and lat for the rectangle: 
     SET lon1 = mylon - dist/abs(cos(radians(mylat)) * 69); 
     SET lon2 = mylon + dist/abs(cos(radians(mylat)) * 69); 
     SET lat1 = mylat - (dist/69); 
     SET lat2 = mylat + (dist/69); 

     -- run the query: 
     SELECT `id`, `user_id`, `activity`, `geo_lat`, `geo_long`, `data`, `date_created`, 
     7912 * ASIN(SQRT(POWER(SIN((mylat - activity_logs.geo_lat) * pi()/180/2), 2) + 
     COS(mylat * pi()/180) * COS(activity_logs.geo_lat * pi()/180) * POWER(SIN((mylon - activity_logs.geo_long) * pi()/180/2), 2) )) as distance 
     FROM activity_logs 
     WHERE 1 
     AND activity_logs.geo_long BETWEEN lon1 AND lon2 
     AND activity_logs.geo_lat BETWEEN lat1 AND lat2 
     HAVING distance < dist ORDER BY date_created DESC LIMIT 100; 

    END WHILE location_loop; 
    CLOSE location_cursor; 
    SET no_more_locations = 0; 

END $$ 

DELIMITER ; 

回答

1

想到的最簡單的方法是創建一個臨時表來存儲3個結果,然後查詢從臨時表中的3個結果從過程的最終結果。

另一種方法是用子查詢將所有查詢重寫到一個查詢中,這就是我自己可能會這樣做的方式,如果我從頭開始編寫它,因爲它會比使用臨時表更快。