我正在尝试使用Postgres PostGIS在Ruby On Rails上执行此操作。
我正在尝试进行分组并依靠我所拥有的有序列表中的城市。
我有一个最近点到我坐标的有序列表(110.1862202 1.6031959)。
现在我想按城市分组并计算每个城市的项目数量。 但是,格式是正确的,但不知何故它已经失去了它的排序。我希望这些城市的排序最接近我的坐标。最重要的是要到最近的城市,但现在它没有排序最近。
查询问题组和计数子查询
scope :nearestcitysubquery, -> () {
from(Treasure.order("ST_Distance(treasures.location_point,
ST_GeographyFromText('SRID=4326;POINT(110.1862202 1.6031959)'))"),
"subquery_treasure_nearest").group("city").count
}
实际结果
=> {"Kuala Lumpur"=>1, "null"=>1, "Sungai Besar"=>1, "Sungai Udang"=>1, "Kuching"=>1}
预期结果
=> {"Kuching"=>1, "Sungai Besar"=>1, "Sungai Udang"=>1, "Kuala Lumpur"=>1, "null"=>1}
我的订购查询工作正常
Treasure.order("ST_Distance(treasures.location_point,
ST_GeographyFromText('SRID=4326;POINT(110.1862202 1.6031959)'))")
订购结果(正确)
=> #<ActiveRecord::Relation [#<Treasure id: 5, user_id: 1, treasure_name: "Kucing", treasure_image: nil, description: "Kucing", hint: nil, location: "Jalan Ke Puncak Serapi", created_at: "2016-01-08 03:46:40", updated_at: "2016-01-08 03:46:40", treasure_id: "TRKKY", location_point: #<RGeo::Geographic::SphericalPointImpl:0x3fe9942b71c8 "POINT (110.18 1.6)">, city: "Kuching", state: "Sarawak", country: "Malaysia", difficulty: 2, google_place_id: "ChIJZf_iRaYF-zERMH5qt30cJJw", size: 2>, #<Treasure id: 4, user_id: 1, treasure_name: "Lori", treasure_image: nil, description: "Lori", hint: nil, location: "Jalan Samsudin", created_at: "2016-01-08 03:45:26", updated_at: "2016-01-08 03:45:26", treasure_id: "T3UKD", location_point: #<RGeo::Geographic::SphericalPointImpl:0x3fe9942bbd68 "POINT (102.14 2.27)">, city: "Sungai Udang", state: "Melaka", country: "Malaysia", difficulty: 2, google_place_id: "ChIJq6_zCZX50TERBdlr6V1CMDg", size: 2>, #<Treasure id: 3, user_id: 1, treasure_name: "Kapal", treasure_image: nil, description: "Kapal", hint: nil, location: "Unnamed Road", created_at: "2016-01-07 09:21:07", updated_at: "2016-01-07 09:21:07", treasure_id: "T3XQR", location_point: #<RGeo::Geographic::SphericalPointImpl:0x3fe9942ba29c "POINT (101.76 3.5)">, city: "null", state: "Selangor", country: "Malaysia", difficulty: 2, google_place_id: "ChIJWU_xuCoTzDERsigXByaXof4", size: 3>, #<Treasure id: 1, user_id: 1, treasure_name: "Kelapa", treasure_image: nil, description: "Food", hint: nil, location: "Jalan Kiara 3", created_at: "2016-01-07 06:08:56", updated_at: "2016-01-07 06:08:56", treasure_id: "TJKQL", location_point: #<RGeo::Geographic::SphericalPointImpl:0x3fe9943647d8 "POINT (101.65 3.17)">, city: "Kuala Lumpur", state: "Wilayah Persekutuan Kuala Lumpur", country: "Malaysia", difficulty: 2, google_place_id: "ChIJ8fBgm-1IzDERPHAF2dYtWTc", size: 2>, #<Treasure id: 2, user_id: 1, treasure_name: "Pulau", treasure_image: nil, description: "Pulau", hint: nil, location: "Jalan Parit 4 Barat", created_at: "2016-01-07 09:20:47", updated_at: "2016-01-07 09:20:47", treasure_id: "TO1BR", location_point: #<RGeo::Geographic::SphericalPointImpl:0x3fe9942bd744 "POINT (101.0 3.7)">, city: "Sungai Besar", state: "Selangor", country: "Malaysia", difficulty: 2, google_place_id: "ChIJAfwEx2lgyzERU_zVy8TqaW0", size: 3>]>
注意:我被告知子查询没有命令,可能外连接可能有效。如何创建这样的查询?
答案 0 :(得分:3)
实际上有一些事情正在阻止你的订单工作。
首先,正如您所提到的,子查询中的任何ORDER
子句 - 您的位置查询所在的子句 - 将与最终结果集的顺序无关。
其次,您的GROUP BY city
子句在逻辑上无法明确地订购结果。假设您在城市X中有宝藏A,距离= 10,城市Y中的宝藏B,距离= 15,城市X中的宝藏C,距离= 20。 City X会在你的结果中排在第一位或最后一位吗?
但是,我认为假设所有城市都包含大致类似区域的宝藏是合理的,所以最近的宝藏订购是合理的。所以我们可以解决这个问题。
最后,Rails&#39; group().count
当前输出值的哈希值。那个API可能是相当新的并且可能会改变(在我看来,哈希真的不应该被订购,并且格式不是非常可扩展的)。所以依靠它可能是一个坏主意。但是,根据我的测试,它 以请求的顺序吐出结果。
简而言之,我们需要做的是将order
移至查询的顶级。为此,订单子句需要使用聚合函数(我将选择MIN,按最近的宝藏订购),我们可以删除花哨的.from
代码:
# I'm assuming this is on the Treasure model
scope :nearestcitysubquery, -> () {
group('city')
.order("MIN(ST_Distance(treasures.location_point,
ST_GeographyFromText('SRID=4326;POINT(110.1862202 1.6031959)')))")
.count
}