如何使这个地理距离SQL查询Postgres兼容

时间:2015-10-10 12:45:36

标签: sql postgresql postgis

我正在尝试使用的库采用给定的纬度和经度,并且使用表中的条目在距离此一定距离内具有lat / lng。生成的SQL查询适用于MySQL,但不适用于PostgreSQL。

以下是我的server.log文件中的条目,详细说明了psql提供的错误以及完整查询:

ERROR:  column "distance" does not exist at character 507
STATEMENT:  select *, ( '3959' * acos( cos( radians('53.49') ) * cos( radians( places.lat ) ) * cos( radians( places.lng ) - radians('-2.38') ) + sin( radians('53.49') ) * sin( radians( places.lat ) ) ) ) AS distance from (
                        Select *
                        From places
                        Where places.lat Between 53.475527714192 And 53.504472285808
                        And places.lng Between -2.4043246788967 And -2.3556753211033
                    ) As places where "places"."deleted_at" is null having "distance" <= $1 order by "distance" asc

知道SQL应该是什么我然后可以编辑生成它的PHP代码并将PR发送回库。

2 个答案:

答案 0 :(得分:4)

查询使用特定于MySql的语法。在Postgres(以及我所知道的所有其他RDBMS)中,您应该使用派生表:

module mux2x1 #(parameter W = 1)
             (input [W-1:0] A,
              input [W-1:0] B,
              input S,
              output [W-1:0] O);

  wire [W-1:0] AO, BO;
  wire NOT_S;
  genvar i;

  not n1(NOT_S, S);     // NOT_S = ~S;
  generate begin
    for (i = 0; i < W; i = i + 1) begin : mux_w
      and a1(AO[i], A[i], NOT_S),    // AO[i] = A[i] & ~S;
          a2(BO[i], B[i], S);        // BO[i] = B[i] & S;
      or  o1(O[i], BO[i], AO[i]);    // O[i] = (A[i] & ~S) | (B[i] & S);
    end
  end

endmodule

我还从数字常量中删除了引号。

答案 1 :(得分:1)

您的查询所做的是用长查询替换postgresql的ST_Dwithin函数。

  

ST_DWithin - 如果几何在指定范围内,则返回true   彼此的距离。对于几何单元,在空间中   参考和地理单位是米,测量是   默认为use_spheroid = true(测量球体周围),速度更快   check,use_spheroid = false来测量球体。

它非常简单

ST_DWithin(geometry1, geometry2)

其中geometry1和geometry2可以是点域(但它们可以是其他几何数据类型两个)

因此您的查询可能会变为

SELECT * FROM places WHERE
 ST_DWithin(ST_GeomFromText('POINT(-71.060316 48.432044)', 4326), places.geom) ORDER BY ST_Distance (ST_GeomFromText('POINT(-71.060316 48.432044)', 4326), places.geom)

您需要做的唯一更改是将lat,lng组合到一个POINT字段中。 (即使在mysql中你也可能应该这样做)。您可以继续将lat,lng放在单独的列中,但是您将牺牲使用正确的地理类型可以获得的收益。

使用ST_Dwithin将比手动距离查询更快,因为它旨在利用postgresql上可以编制索引的几何列。

如果你想有一天想回到mysql怎么办?好吧mysql 5.7添加了St_Dwithin功能。