我有一個問題,優化SQL查詢,並利用活動記錄生成查詢。它涉及選擇關聯的id和計數,以及具有變量輸入的條件連接。此外,我還沒有能夠使用where語句,因爲我想要的結果還沒有任何關聯。 我的型號如下活動記錄,SQL:有選擇和計數的關聯連接狀態
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
我已經有場地,catering_events(簡稱事件)和用戶。用戶可以爲每個事件投1票,其中投票是用戶,選擇場地,事件(user_id,venue_id和catering_event_id)。
在節目活動頁面,我想顯示所有場館和他們的投票計數,其中不計票地點顯示爲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>
]
這將返回所有場館及其votecounts餐飲活動1。但是,我必須命名vote_count一些屬性在我稱之爲find_by_sql的模型上,並且由於投票有3個條件,因此我可以添加投票計數屬性的無1模型。當我嘗試命名空間中的計數的自定義字段,我沒有得到一個具有@屬性作爲文檔說,它只是省略了值:
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}
通知第一加入發言,我只好硬編碼2:
AND votes.catering_event_id = 2
我havnt想出如何一個變量傳遞給活動記錄加入聲明。
總之,我試圖使用find_by_sql或活動記錄(我的首選項是活動記錄)的直接sql執行單個查詢,選擇所有場所以及它們對變量catering_event的投票計數。我寧願調整當前的解決方案之一,以允許find_by_sql返回自定義的名稱間隔屬性,或者找出如何正確傳遞聯接語句和插值/清理變量。
我是on Rails的4.2.1和Ruby 2.2.0