【问题标题】:Calculate a new column in rails activerecord query在 rails activerecord 查询中计算新列
【发布时间】:2018-11-13 17:48:23
【问题描述】:

我有一个返回 100,000 多条记录的现有查询。

dev_results = records.joins("INNER JOIN devices ON (devices.id = snapshots.type_id)")
  .joins("INNER JOIN assets ON (devices.asset_id = assets.id)")
  .joins("LEFT JOIN systems ON (assets.system_id = systems.id)")
  .pluck("devices.hostname, devices.ipaddress, systems.fismaid, assets.is_expired")

Device 模型有一个作用域:

  scope :dhcp, -> {
joins("INNER JOIN dhcp_cidrs ON (devices.ipaddress <<= dhcp_cidrs.cidr)").where("devices.id NOT IN (?)", Device.reserved.select("devices.id"))

}

如果 devices.id 在 dhcp_ids 中,我如何使用 Device.dhcp 作为子查询来计算名为“is_dhcp”的新列 = true(否则,is_dhcp = false)

【问题讨论】:

  • 您使用的是哪个数据库?
  • 我正在使用 PostgresQL

标签: sql ruby-on-rails postgresql activerecord ruby-on-rails-5.2


【解决方案1】:

pluck() 支持多种数据库命令。在许多 DBMS 中,您可以使用 IF-THEN-ELSE 构造。在 PostgresQL 中,您必须使用 CASE-WHEN-THEN-ELSE-END 构造。

首先,您可以使用 model.scope 创建 CASE 构造,如下所示:

dhcp_device_ids = Device.dhcp.select('devices.id').to_sql
dhcp_calculation = "CASE WHEN (devices.id IN (#{dhcp_device_ids})) THEN TRUE ELSE FALSE END"

接下来,你可以在 pluck() 中使用这个计算

.pluck("devices.hostname, devices.ipaddress, systems.fismaid, assets.is_expired, #{dhcp_calculation}")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多