2011-10-03 57 views
1

我正在嘗試使用ActiveRecord和/或SQL查找補充。ActiveRecord中的補充?

我有「註釋」,每個有兩個相關領域的集合:對應於誰執行的 註釋用戶

  • session_datum_id。空表示它尚未完成。
  • post_id表示註釋是'約'的帖子。不能 爲空。

每個post_id可能有多個註釋。

我想有效地找到滿足兩個約束的註釋:

  1. session_datum_id爲空。這意味着此特定註釋尚未執行。
  2. 作爲arg傳入的session_datum尚未執行具有相同post_id的另一個註釋。

這是一個非常天真的版本,它在數據庫之外進行連接。它會查找此用戶已執行的所有註釋,並從仍需執行的註釋的詳盡列表中刪除這些post_id。然後,隨機選取從結果列表:

def self.random_empty_unseen(session_datum) 
    mine = where('session_datum_id = ?', session_datum) 
    elligible = where('session_datum_id IS NULL') 
    mine.each do |i| 
    elligible.each do |j| 
     if (i.post_id == j.post_id) 
     elligible.delete(j) 
     end 
    end 
    end 
    elligible[rand(elligible.count)] 
end 

作爲註釋的名單會越來越大,這將非常陷入癱瘓。我可以想象一個概率算法,我們隨機選擇一個符合條件的註釋,然後檢查用戶是否已經執行了它(重試,如果是的話),但有退化的情況下,將無法工作。 (大量的註釋和用戶已經執行除了其中之一以外的其他所有內容。)

是否存在對此的封閉表單查詢,或許使用NOT EXISTS?

+0

它會讓你的生活更容易添加唯一性約束嗎?如果您只允許一個註釋在用戶/帖子配對之前存在,那麼您不必擔心第二個約束。你必須找到一種不同的方式來表明完整性,雖然... –

+0

不幸的是,問題域需要這個。將註釋看作機械特克風格任務。我們希望每個任務都由多個人完成,但沒有人能夠多次完成相同的任務。每個任務去一個人打破了這個問題的限制。 –

回答

1
SELECT a1.* 
FROM annotations AS a1 
JOIN annotations AS a2 
ON a1.post_id=a2.post_id 
WHERE a2.session_datum_id=session_datum AND a1.session_datum_id IS NULL