【问题标题】:How to use SQL using Active Record如何通过 Active Record 使用 SQL
【发布时间】:2019-05-30 17:12:55
【问题描述】:

我正在尝试优化 Active Record 中查询的性能。以前我会做两个 SQL 查询,应该可以一次完成。

这些是我正在运行查询的表:

# Table name: notifications
#
#  id         :integer          not null, primary key
#  content    :text(65535)
#  position   :integer

# Table name: dismissed_notifications
#
#  id              :integer          not null, primary key
#  notification_id :integer
#  user_id         :integer

这是现有的查询:

where.not(id: user.dismissed_notifications.pluck(:id))

产生:

SELECT `dismissed_notifications`.`id` FROM `dismissed_notifications` WHERE `dismissed_notifications`.`user_id` = 655

SELECT  `notifications`.* FROM `notifications` WHERE (`notifications`.`id` != 1)

这是我想要得到的 SQL,它返回相同的记录:

select *
from notifications n
where not exists(
    select 1
    from dismissed_notifications dn
    where dn.id = n.id
      and dn.user_id = 655)

【问题讨论】:

  • 在我看来像是 outer_join 的任务

标签: ruby-on-rails ruby activerecord


【解决方案1】:

你可以像下面这样写not exists查询

where('NOT EXISTS (' + user.dismissed_notifications.where('dismissed_notifications.id = notifications.id').to_sql + ')')

还有另一种减少查询数量的方法是使用select 而不是pluck,它将创建子查询而不是从数据库中提取记录。 Rails ActiveRecord Subqueries

where.not(id: user.dismissed_notifications.select(:id))

下面会生成SQL查询

SELECT  `notifications`.* 
  FROM `notifications` 
  WHERE (
    `notifications`.`id` NOT IN 
      (SELECT `dismissed_notifications`.`id` 
        FROM `dismissed_notifications` 
        WHERE `dismissed_notifications`.`user_id` = 655
      )
  )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    相关资源
    最近更新 更多