一对多查询加入

时间:2009-09-12 22:54:20

标签: ruby-on-rails

我有一个书模型,一个标签模型和一个连接模型。书籍模型通过连接模型有许多标签。如何找到标有'A'和标签'B'的书籍?

这适用于Just A:

Book.all(:joins => 'tags', :conditions => {'tags.name' => 'A'})

这适用于A或B(或似乎):

Book.all(:joins => 'tags', :conditions => {'tags.name' => ['A','B']})

但是我想找到A和B的所有书籍。

3 个答案:

答案 0 :(得分:0)

这是一种方法:查找所有书籍并删除没有标签A和B的书籍

Book.all - Book.all(:joins=>'tags', :conditions=>[tags.name <> 'A' and tags.name <> 'B']

答案 1 :(得分:0)

这应该这样做:

Book.all(:joins => 'tags', :conditions => "tags.name = 'A' and tags.name = 'B'")

答案 2 :(得分:0)

我能想到的唯一方法是在连接表上使用多个连接,每个连接对应一个AND标记。这不能很好地扩展,但适用于两个。您想要的查询,假设您的连接模型称为带有外键book_id的标记:

SELECT DISTINCT books.* FROM books 
  INNER JOIN taggings t1 ON t1.book_id = book.id 
  INNER JOIN taggings t2 ON t2.book_id = book.id 
WHERE t1.id = (SELECT id FROM tags WHERE name = 'A') 
  AND t2.id = (SELECT id FROM tags WHERE name = 'B')

你可以尝试使用find方法,祝你好运:)可能更容易使用find_by_sql,就像这样:

Book.find_by_sql(["SELECT DISTINCT books.* FROM books 
      INNER JOIN taggings t1 ON t1.book_id = book.id 
      INNER JOIN taggings t2 ON t2.book_id = book.id 
    WHERE t1.id = (SELECT id FROM tags WHERE name = ?) 
      AND t2.id = (SELECT id FROM tags WHERE name = ?)", 'A', 'B')

这假定tags.name是唯一的。