2016-06-24 5 views
1

私はLaravel 5.2を使用しており、クエリビルダー関数を使用してSQLクエリを実行しており、MySQLデータベースからPostgreSQLに切り替えるときにクエリが壊れています。クエリは、特定の数マイルの緯度と経度のすべての場所を取得するためのものです。一度PostgreSQLのデータ・ソースへの切り替えPHPでのSQL構文Laravel Query Builder PostgreSQLvs MySQL

$locations = Location::select(
     DB::raw("*, 
      (3959 * acos(cos(radians(?)) * 
       cos(radians(lat)) 
       * cos(radians(long) - radians(?) 
       ) + sin(radians(?)) * 
       sin(radians(lat))) 
      ) AS distance")) 
     ->having("distance", "<", $distance) 
     ->orderBy("distance") 
     ->setBindings([$latitude, $longitude, $latitude]) 
     ->get(); 

、私はこのエラーを取得する:

QLSTATE[42703]: Undefined column: 7 ERROR: column "distance" does not exist 
LINE 7:) AS distance from "locations" having "distance" < $4 o... 
^ (SQL: select *, 
(3959 * acos(cos(radians(37.7959362)) * 
cos(radians(lat)) 
* cos(radians(long) - radians(-122.4000032) 
) + sin(radians(37.7959362)) * 
sin(radians(lat))) 
) AS distance from "locations" having "distance" < 15 order by "distance" asc) 

この問題を解決するための最良の方法だろう何。私はそれがLaravelによって作成されたMySQLとPostgresの間のSQL構文の違いだが、私はこのエラーを修正する方法を見つけようと努力している。

ご協力いただければ幸いです!

答えて

1

問題はhavingです。 PostgreSQLではhaving句で派生カラム(またはカラムエイリアス)を使用することはできませんが、MySQLは(デフォルトで有効になっているMySQL拡張機能を有効にしている限り)使用できます。

この制限を回避する1つの方法は、フィールドがhaving句で使用できるように派生テーブルを使用することです。以下のようなもの(警告:完全にテストされていない):

$locations = Location::from(DB::raw("(select *, 
     (3959 * acos(cos(radians(?)) * 
      cos(radians(lat)) 
      * cos(radians(long) - radians(?) 
      ) + sin(radians(?)) * 
      sin(radians(lat))) 
     ) AS distance from locations) as t")) 
    ->having("distance", "<", $distance) 
    ->orderBy("distance") 
    ->setBindings([$latitude, $longitude, $latitude]) 
    ->get(); 
+0

ありがとう@patricus!派生テーブルを使用するというあなたの提案を使用して、ソリューションに到達することができました。私はこのように見えるgroup by節を追加しなければならなかった: - > groupBy(DB :: raw( 'id、title、address_1 ...'))。 –