2

使用Rails的4.2和Postgres我创建了以下查询,给我一个鸟类id在目击表中按照每只鸟的目击次数排序的uniq列表。另外请注意我使用Kaminari宝石作为分页。如何结合postgres群体的数量和在哪里

Sighting.select("bird_id, COUNT(sightings.id) as sightings_count").group(:bird_id).order('sightings_count DESC').page(1) 

这很好的回报了ActiveRecordRelation的意图。问题就出现了,当我尝试将其与地理编码宝石.near方法

Sighting.near([-31.0, 151.0], 1000, units: :km).select("bird_id, COUNT(sightings.id) as sightings_count").group(:bird_id).order('sightings_count DESC').page(1) 

这生成查询和错误

SELECT sightings.*, 6371.0 * 2 * ASIN(SQRT(POWER(SIN((-31.0 - sightings.lat) * PI()/180/2), 2) + COS(-31.0 * PI()/180) * COS(sightings.lat * PI()/180) * POWER(SIN((151.0 - sightings.lng) * PI()/180/2), 2))) AS distance, MOD(CAST((ATAN2(((sightings.lng - 151.0)/57.2957795), ((sightings.lat - -31.0)/57.2957795)) * 57.2957795) + 360 AS decimal), 360) AS bearing, bird_id, COUNT(sightings.id) as sightings_count FROM "sightings" WHERE (sightings.lat BETWEEN -39.993216059187304 AND -22.006783940812696 AND sightings.lng BETWEEN 140.50821379697885 AND 161.49178620302115 AND (6371.0 * 2 * ASIN(SQRT(POWER(SIN((-31.0 - sightings.lat) * PI()/180/2), 2) + COS(-31.0 * PI()/180) * COS(sightings.lat * PI()/180) * POWER(SIN((151.0 - sightings.lng) * PI()/180/2), 2)))) BETWEEN 0.0 AND 1000) GROUP BY bird_id ORDER BY distance ASC, sightings_count DESC LIMIT 25 OFFSET 0 

PG :: GroupingError结合:ERROR:列 “sightings.id” 绝出现在GROUP BY子句中或用于聚合函数

通过将鸟数计数不正确,并且据我了解,COUNT中的COUNT是一个聚合函数,其中包含sightings.id 。

我怎样才能成功地结合这两个?

注意:我确实尝试了以下操作,但返回的是哈希而非AR关系。

Sighting.near([@lat, @lng], @range, units: :km, order:nil).group(:bird_id).order('count_id DESC').page(@page).count(:id) 

感谢您的任何帮助!

+0

问题是'geocoder'生成'SELECT'列和'ORDER BY distance',如果你使用GROUP BY(也会产生上面的错误),这两个都没有意义 - 我还没有发现了任何可以关闭它的东西;在geocoder的github页面的[已知问题](https://github.com/alexreisner/geocoder#known-issue)部分中提到了类似的东西。 – pozs 2015-02-06 08:49:42

回答

1

创建一个自定义近景是最简单的工作,因为我没有使用方位或距离属性添加到每条记录,因此我靠近生成的整个选择sql并不需要。而不是选择(选项[:选择]),我用我想要的选择替换它。

scope :birds_by_sighting, lambda{ |location, *args| 
latitude, longitude = Geocoder::Calculations.extract_coordinates(location) 
if Geocoder::Calculations.coordinates_present?(latitude, longitude) 
    options = near_scope_options(latitude, longitude, *args) 
    select("bird_id, COUNT(sightings.id) as sightings_count").group(:bird_id).where(options[:conditions]).order('sightings_count DESC') 
else 
    # If no lat/lon given we don't want any results, but we still 
    # need distance and bearing columns so you can add, for example: 
    # .order("distance") 
    select(select_clause(nil, null_value, null_value)).where(false_condition) 
end 
}