如何在SQL中选择至少具有N个类似外键的文档

时间:2014-11-29 05:47:19

标签: sql ruby-on-rails postgresql relational-division

 doc.id|tag.id|taggings.id|    name

  3 |  3 |  3 | heroku
  3 |  4 |  4 | javascript
  3 |  5 |  5 | html
  4 |  4 |  6 | javascript
  4 |  3 |  7 | heroku
  4 |  5 |  8 | html
  4 |  6 |  9 | swagger

我有这张桌子

我想选择至少具有N个相同标签的元素

所以我们假设用html和heroku标记的文档。

我想要返回doc 3和doc 4 [在此表中它将是表中唯一的两件事。大声笑但仍然!]

4 个答案:

答案 0 :(得分:2)

这是countcase的一种方式:

select id
from documents
group by id
having count(case when name = 'html' then 1 end) > 0
   and count(case when name = 'heroku' then 1 end) > 0

答案 1 :(得分:2)

一般来说,范围将采用以下格式:

class Doc
   has_and_belongs_to_many :tags

   scope :tagged_with(*list), -> {|list| joins(:tags).merge(Tag.named(*list)) }
end

class Tag
   has_and_belongs_to_many :docs

   scope :named(*list), -> {|list| where(name: list) }
end

我不确定where(name: list)是否能正常工作,所以只需用arel替换范围。

scope :named(*list), -> {|list| where(arel_table[:name].in(list)) }

用法:

Doc.tagged_with(:html, :heroku)

答案 2 :(得分:1)

select doc_id
from mytable
where name in ('html','heroku')
group by doc_id
having count(distinct name) = 2

答案 3 :(得分:0)

据我所知:

SELECT doc_id, count(*) AS ct
FROM   doc_tag
WHERE  tag_id IN (3,4,5)  -- "the same tags"
GROUP  BY 1
HAVING count(*) >= 3;     -- at least N of those

SQL Fiddle.