ruby - ActiveRecord 子查询内部连接

标签 ruby activerecord postgis arel rgeo

我正在尝试将“原始”PostGIS SQL 查询转换为 Rails ActiveRecord 查询。我的目标是将两个连续的 ActiveRecord 查询(每个耗时约 1ms)转换为单个 ActiveRecord 查询(耗时约 1ms)。将下面的 SQL 与 ActiveRecord::Base.connection.execute 结合使用我能够验证时间的减少。

因此,我的直接请求是帮助我将此查询转换为 ActiveRecord 查询(以及执行它的最佳方式)。

SELECT COUNT(*)
FROM "users"
INNER JOIN (
  SELECT "centroid"
  FROM "zip_caches"
  WHERE "zip_caches"."postalcode" = '<postalcode>'
) AS "sub" ON ST_Intersects("users"."vendor_coverage", "sub"."centroid")
WHERE "users"."active" = 1;

注意<postalcode>是此查询中唯一的可变数据。很明显,这里有两个模型UserZipCache . UserZipCache没有直接关系.

当前的两步 ActiveRecord 查询如下所示。

zip = ZipCache.select(:centroid).where(postalcode: '<postalcode>').limit(1).first
User.where{st_intersects(vendor_coverage, zip.centroid)}.count

最佳答案

免责声明:我从未使用过 PostGIS

首先,在您的最终请求中,您似乎错过了 WHERE "users"."active"= 1; 部分。

这是我要做的:

首先在用户上添加一个active范围(为了可重用性)

scope :active, -> { User.where(active: 1) }

然后对于实际查询,您可以在不执行子查询的情况下将其用于用户模型的连接中,例如:

subquery = ZipCache.select(:centroid).where(postalcode: '<postalcode>')
User.active
    .joins("INNER JOIN (#{subquery.to_sql}) sub ON ST_Intersects(users.vendor_coverage, sub.centroid)")
    .count

这允许最少的原始 SQL,同时只保留一个查询。

在任何情况下,通过将记录器级别设置为调试,检查控制台/日志中实际的 sql 请求。

关于ruby - ActiveRecord 子查询内部连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27993979/

相关文章:

javascript - 如何使用 Ruby 验证 webhook? (在 rails 中)

ruby-on-rails - has_one/has_many rails 与主键以外的备用源 ID 关联

database - 使用特殊格式的多段线将数据从 csv 文件复制到 postgres+postgis

leaflet - 在传单中创建一个 cql 过滤器

postgresql - 根据输入数据填充 x、y 或 long、lat 字段,并根据输入创建点

Ruby 的线程速度

ruby-on-rails - 在 Passenger Rails 应用程序中包含 ~/opt/lib 库

ruby-on-rails - ActiveRecord 类方法返回 `self` 丢失间接引用

ruby-on-rails - RoR : has_one "or the other"?(或者,没有继承的多态性。)

ruby-on-rails - 我的 Rails 应用程序外部端点的集成测试的良好做法?