2011-10-03 38 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