如何从轨道上的ruby上的有序列表中的count子查询进行排序和分组

时间:2016-02-15 10:11:13

标签: sql ruby-on-rails postgresql group-by

我正在尝试使用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>]>

注意:我被告知子查询没有命令,可能外连接可能有效。如何创建这样的查询?

1 个答案:

答案 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
}