【发布时间】:2015-04-06 07:46:56
【问题描述】:
使用 Rails 4.2 和 Postgres 我创建了以下查询,以在 Sightings 表中为我提供一个唯一的鸟类 id 列表,该列表按每只鸟的目击次数排序。另请注意,我使用 Kaminari gem 进行分页。
Sighting.select("bird_id, COUNT(sightings.id) as sightings_count").group(:bird_id).order('sightings_count DESC').page(1)
返回预期的 ActiveRecordRelation 效果很好。当我尝试将它与地理编码器 gem .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: column "sightings.id" 必须出现在 GROUP BY 子句中或在聚合函数中使用
通过鸟类数量不正确的方式将 id 添加到组中,据我所知,select 中的 COUNT 是一个聚合函数,其中确实包含了Sightings.id。
如何才能成功地将两者结合起来?
注意:我确实尝试了以下方法,但这会返回一个 Hash 而不是 AR Relation。
Sighting.near([@lat, @lng], @range, units: :km, order:nil).group(:bird_id).order('count_id DESC').page(@page).count(:id)
感谢您的帮助!!
【问题讨论】:
-
问题是
geocoder生成SELECT列和ORDER BY distance,如果你使用GROUP BY,这两个都是没有意义的(并且还会生成上面的错误)——我还没有找到任何可以关闭它的东西; geocoder's github page的Known Issue部分提到了类似的东西。
标签: ruby-on-rails postgresql rails-geocoder ruby-on-rails-4.2