mysql - 事件记录,SQL : select and count association with joins condition

标签 mysql activerecord count outer-join

我在优化 SQL 查询和利用事件记录生成查询时遇到问题。它涉及选择关联的 ID 和计数,以及具有可变输入的条件连接。此外,我无法使用 where 语句,因为我想要的结果还没有任何关联。 我的模型如下

class Vote < ActiveRecord::Base
  belongs_to :user
  belongs_to :venue
  belongs_to :catering_event
  validates :catering_event_id, uniqueness: { scope: :user_id }
end

class Venue < ActiveRecord::Base
  has_many :votes
  has_many :catering_events, through: :votes
  has_many :users, through: :votes
end

class CateringEvent < ActiveRecord::Base
  has_many :votes
  has_many :venues, through: :votes
  has_many :users, through: :votes  
end

我有的是 field 、catering_events(简称事件)和用户。用户可以为每个事件投 1 票,其中一票是用户为一个事件(user_id、venue_id 和 catering_event_id)选择 field 。

在演出事件页面上,我想显示所有场馆及其票数,没有票数的场馆显示票数为 0,我试图通过一个查询来完成。我无法使用 where 子句,因为我的尝试过滤掉了尚未投票的地点。

我目前有两个功能解决方案,我对这两个都不满意。第一个是直接的 find_by_sql 查询;但是我必须半破解返回值,因为 find_by_sql 只返回模型当前具有的属性。

对于我当前的数据:

#<Vote:0x007fb9f681ac38 id: 1, user_id: 2, venue_id: 3, catering_event_id: 1>,
#<Vote:0x007fb9f681aa58 id: 2, user_id: 1, venue_id: 2, catering_event_id: 1>,
#<Vote:0x007fb9f681a8f0 id: 3, user_id: 1, venue_id: 1,  catering_event_id: 2>

我的功能 find_by_sql 查询:

sql =     
"SELECT COUNT(votes.id) AS id, venues.id AS venue_id 
FROM venues 
LEFT OUTER JOIN votes ON votes.venue_id = venues.id 
AND votes.catering_event_id = ? 
LEFT OUTER JOIN catering_events ON catering_events.id = votes.catering_event_id 
GROUP BY venues.id"

=> "SELECT COUNT(votes.id) AS id, venues.id AS venue_id FROM venues LEFT OUTER JOIN votes ON votes.venue_id = venues.id AND votes.catering_event_id = ? LEFT OUTER JOIN catering_events ON catering_events.id = votes.catering_event_id GROUP BY venues.id"

pry(main)> Vote.find_by_sql [sql, '1']
Vote Load (9.0ms)  SELECT COUNT(votes.id) AS id, venues.id AS venue_id FROM venues LEFT OUTER JOIN votes ON votes.venue_id = venues.id AND votes.catering_event_id = '1' LEFT OUTER JOIN catering_events ON catering_events.id = votes.catering_event_id GROUP BY venues.id

=> [
  #<Vote:0x007fb9f33ca8c0 id: 0, venue_id: 1>, 
  #<Vote:0x007fb9f33ca668 id: 1, venue_id: 2>, 
  #<Vote:0x007fb9f33ca258 id: 1, venue_id: 3>
]

这将返回餐饮事件 1 的所有 field 及其投票数。但是,我必须将 vote_count 命名为我从中调用 find_by_sql 的模型的某个属性,并且因为投票有 3 个条件,所以没有 1 个模型可供我使用可以添加一个 votecount 属性。当我尝试将计数命名空间命名为自定义字段时,我没有得到 @attributes has 文档所说的,它只是省略了值:

Vote Load (0.7ms)  SELECT COUNT(votes.id) AS vote_count, venues.id AS venue_id 
FROM venues 
LEFT OUTER JOIN votes ON votes.venue_id = venues.id 
AND votes.catering_event_id = '1' 
LEFT OUTER JOIN catering_events ON catering_events.id = votes.catering_event_id 
GROUP BY venues.id
=> [
  #<Vote:0x007fb9f31d29a0 id: nil, venue_id: 1>, 
  #<Vote:0x007fb9f31d2248 id: nil, venue_id: 2>, 
  #<Vote:0x007fb9f31d1c58 id: nil, venue_id: 3>
]

我制定的第二个解决方案涉及使用事件记录进行查询,但是我还没有想出如何使用变量 catering_event_id 正确清理连接语句: (我实际上并没有在新行上运行它,但为了便于阅读,我把它分开了)

Venue.select('venues.id as venue_id')
  .joins('LEFT OUTER JOIN votes ON votes.venue_id = venues.id AND votes.catering_event_id = 2')
  .joins('LEFT OUTER JOIN catering_events ON catering_events.id = votes.catering_event_id').group('venues.id')
  .count('votes.id')
(0.6ms)  SELECT COUNT(votes.id) AS count_votes_id, venues.id AS venues_id FROM `venues` LEFT OUTER JOIN votes ON votes.venue_id = venues.id AND votes.catering_event_id = 2 LEFT OUTER JOIN catering_events ON catering_events.id = votes.catering_event_id GROUP BY venues.id
=> {1=>1, 2=>0, 3=>0}

注意第一个 joins 语句,我不得不硬编码 2 in:

AND votes.catering_event_id = 2

因为我还没有弄清楚如何将变量传递给事件记录连接语句。

总而言之,我正在尝试使用带有 find_by_sql 的直接 sql 或事件记录(我的偏好是事件记录)执行单个查询,以选择所有 field ,以及他们对变量 catering_event 的投票计数。我更愿意调整我当前的解决方案之一,以允许 find_by_sql 返回自定义 namespace 属性或弄清楚如何正确地将连接语句传递给插值/清理变量。

我在 Rails 4.2.1 和 ruby​​ 2.2.0 上

最佳答案

答案最终在 find_by_sql 中命令。

虽然它没有在返回值中显示它,但在查询中使用 AS 关键字创建了一个虚拟属性。我现在可以执行 SELECT COUNT(votes.id) AS vote_count,虽然返回的对象不显示属性 vote_count,但它们会响应它。

例如

query = Vote.find_by_sql([sql, '1'])
query.map(&:vote_count)
=> [0,1,1]

关于mysql - 事件记录,SQL : select and count association with joins condition,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29416408/

相关文章:

MySQL 简单 COUNT 花费很长时间

php - 点击插入按钮后保留的数据

mysql - 查找关联模型中日期范围内的差距 | Rails 上的 Ruby

Php/Html - 数据库断开连接

ruby-on-rails - 在 Active Record 迁移中可逆和还原

ruby-on-rails - 在Rails中-何时使用它?

SQL 计数为零值

xslt - XSL 2.0 : count total number of unique values

mysql - go mysql 返回空值

php - 尝试仅更新特定行的列值?