如何获取SQL IN子句中出现的次数?

时间:2008-08-28 11:54:03

标签: sql

假设我有四个表:PAGEUSERTAGPAGE-TAG

Table      | Fields
------------------------------------------
PAGE       | ID, CONTENT
TAG        | ID, NAME
USER       | ID, NAME    
PAGE-TAG   | ID, PAGE-ID, TAG-ID, USER-ID

让我说我有四页:

PAGE#1 'Content page 1' tagged with tag#1 by user1, tagged with tag#1 by user2 
PAGE#2 'Content page 2' tagged with tag#3 by user2, tagged by tag#1 by user2, tagged by tag#8 by user1  
PAGE#3 'Content page 3' tagged with tag#7 by user#1
PAGE#4 'Content page 4' tagged with tag#1 by user1, tagged with tag#8 by user1

我希望我的查询看起来像这样:

select page.content ?
from page, page-tag 
where 
page.id = page-tag.pag-id 
and page-tag.tag-id in (1, 3, 8) 
order by ? desc

我想得到这样的输出:

Content page 2, 3
Content page 4, 2
Content page 1, 1

引用Neall

  

你的问题有点令人困惑。您想获得每个页面被标记的次数吗?

没有

  

每个标记获得每个标记的次数?

没有

  

标记了网页的唯一身份用户数量?

  

使用每个标记标记每个页面的唯一身份用户数?

没有

我想知道有多少传递的标签出现在特定页面中,而不仅仅是出现任何标签。

SQL IN就像一个布尔运算符OR。如果页面被标记为IN子句中的任何值,则返回true。我想知道IN子句中有多少值返回true。

下面我展示了我期望的输出:

page 1 | in (1,2)   -> 1

page 1 | in (1,2,3) -> 1

page 1 | in (1)     -> 1

page 1 | in (1,3,8) -> 1

page 2 | in (1,2)   -> 1

page 2 | in (1,2,3) -> 2

page 2 | in (1)     -> 1

page 2 | in (1,3,8) -> 3

page 4 | in (1,2,3) -> 1

page 4 | in (1,2,3) -> 1

page 4 | in (1)     -> 1

page 4 | in (1,3,8) -> 2

这将是我之前提到的页面标记表的内容:

   id       page-id  tag-id  user-id  

    1       1        1       1 

    2       1        1       2 

    3       2        3       2 

    4       2        1       2 

    5       2        8       1 

    6       3        7       1 

    7       4        1       1 

    8       4        8       1 

@Kristof 并不完全是我要搜索的内容,但无论如何都要感谢。

@Daren 如果我执行您的代码,我会收到下一个错误:

#1054 - Unknown column 'page-tag.tag-id' in 'having clause' 

@Eduardo Molteni 你的答案没有给出问题的输出,但是:

Content page 2 8
Content page 4 8
content page 2 3
content page 1 1
content page 1 1
content page 2 1
cotnent page 4 1

@Keith 我使用纯SQL而不是T-SQL,我不熟悉T-SQL,所以我不知道你的查询如何转换为纯SQL。

还有什么想法?

6 个答案:

答案 0 :(得分:2)

这可能有效:

select page.content, count(page-tag.tag-id) as tagcount
from page inner join page-tag on page-tag.page-id = page.id
group by page.content
having page-tag.tag-id in (1, 3, 8)

答案 1 :(得分:1)

好的,所以这和kristof的答案之间的关键区别在于你只需要对第1页显示1的计数,因为它只被标记了来自集合中的一个标记(即使两个单独的用户都标记了它)。

我会建议:

SELECT page.ID, page.content, count(*) AS uniquetags
FROM
   (  SELECT DISTINCT page.content, page.ID, page-tag.tag-id 
      FROM page INNER JOIN page-tag ON page.ID=page-tag.page-ID 
      WHERE page-tag.tag-id IN (1, 3, 8) 
   )
    GROUP BY page.ID

我没有SQL Server安装来检查这一点,所以如果语法错误就道歉。但从语义上来说,我认为这就是你所需要的。

这可能不会按照标签数量的降序给出输出,但请尝试添加:

      ORDER BY uniquetags DESC

最后。我的不确定性是你是否可以在SQL Server中使用ORDER BY分组。如果没有,那么您可能需要将整个事物嵌套在另一个SELECT中。

答案 2 :(得分:0)

在T-Sql中:

select count(distinct name)
from page-tag
where tag-id in (1, 3, 8) 

这将为您计算ID列表中不同标签名称的数量

答案 3 :(得分:0)

同意 Neall ,有点混淆了这个问题。 如果你想要问题中列出的输出,那么sql就像:

一样简单
select page.content, page-tag.tag-id
from page, page-tag 
where page.id = page-tag.pag-id 
and page-tag.tag-id in (1, 3, 8) 
order by page-tag.tag-id desc

但如果你想要tagcount, Daren 已经回答了你的问题

答案 4 :(得分:0)

select 
    page.content, 
    count(pageTag.tagID) as tagCount
from 
    page
    inner join pageTag on page.ID = pageTag.pageID
where 
    pageTag.tagID in (1, 3, 8) 
group by
    page.content
order by
    tagCount desc

它为您提供每页的标签数量;按更高数量的标签排序

我希望我能正确理解你的问题

答案 5 :(得分:0)

Leigh Caldwell的回答是正确的,感谢man,但至少需要在MySQL中添加一个别名。因此查询将如下所示:

SELECT page.ID, page.content, count(*) AS uniquetags FROM
    ( SELECT DISTINCT page.content, page.ID, page-tag.tag-id FROM page INNER JOIN page-tag ON page.ID=page-tag.page-ID WHERE page-tag.tag-id IN (1, 3, 8) ) as page
    GROUP BY page.ID
order by uniquetags desc