4

抱歉,我无法为我的问题提供更好的标题,因为我对 SQL 还很陌生。我正在寻找解决以下问题的 SQL 查询字符串。

让我们假设下表:

DOCUMENT_ID | 标签
----------------------------
   1 | 标签1
   1 | 标签2
   1 | 标签3
   2 | 标签2
   3 | 标签1
   3 | 标签2
   4 | 标签1
   5 | 标签3

现在我想选择所有包含一个或多个标签的不同文档 ID(但必须提供所有指定的标签)。例如:选择所有带有 tag1 和 tag2 的 document_id 将返回 1 和 3(但不是 4,因为它没有 tag2)。

最好的方法是什么?

问候, 凯

4

4 回答 4

14
SELECT document_id
FROM table
WHERE tag = 'tag1' OR tag = 'tag2'
GROUP BY document_id
HAVING COUNT(DISTINCT tag) = 2

编辑:

因缺乏约束而更新...

于 2009-07-29T20:00:42.797 回答
7

这假定 DocumentID 和 Tag 是主键。

编辑:更改 HAVING 子句以计算 DISTINCT 标记。这样,主键是什么并不重要。

测试数据

-- Populate Test Data
CREATE TABLE #table (
  DocumentID varchar(8) NOT NULL, 
  Tag varchar(8) NOT NULL
)

INSERT INTO #table VALUES ('1','tag1')
INSERT INTO #table VALUES ('1','tag2')
INSERT INTO #table VALUES ('1','tag3')
INSERT INTO #table VALUES ('2','tag2')
INSERT INTO #table VALUES ('3','tag1')
INSERT INTO #table VALUES ('3','tag2')
INSERT INTO #table VALUES ('4','tag1')
INSERT INTO #table VALUES ('5','tag3')

INSERT INTO #table VALUES ('3','tag2')  -- Edit: test duplicate tags

询问

-- Return Results
SELECT DocumentID FROM #table
WHERE Tag IN ('tag1','tag2')
GROUP BY DocumentID
HAVING COUNT(DISTINCT Tag) = 2

结果

DocumentID
----------
1
3
于 2009-07-29T20:06:53.923 回答
1
select DOCUMENT_ID
      TAG in ("tag1", "tag2", ... "tagN")
   group by DOCUMENT_ID
   having count(*) > N and 

根据需要调整 N 和标签列表。

于 2009-07-29T20:03:29.670 回答
-1
Select distinct document_id 
from {TABLE} 
where tag in ('tag1','tag2')
group by id 
having count(tag) >=2 

如何在 where 子句中生成标签列表取决于您的应用程序结构。如果您将查询作为代码的一部分动态生成,那么您可以简单地将查询构造为动态生成的大字符串。

我们总是使用存储过程来查询数据。在这种情况下,我们将标签列表作为 XML 文档传入。- 像这样的过程可能看起来像其中一个输入参数的过程

<tags>
   <tag>tag1</tag>
   <tag>tag2</tag>
</tags>


CREATE PROCEDURE [dbo].[GetDocumentIdsByTag]
@tagList xml
AS
BEGIN

declare @tagCount int
select @tagCount = count(distinct *) from @tagList.nodes('tags/tag') R(tags)


SELECT DISTINCT documentid
FROM {TABLE}
JOIN @tagList.nodes('tags/tag') R(tags) ON {TABLE}.tag = tags.value('.','varchar(20)')
group by id 
having count(distict tag) >= @tagCount 

END

或者

CREATE PROCEDURE [dbo].[GetDocumentIdsByTag]
@tagList xml
AS
BEGIN

declare @tagCount int
select @tagCount = count(*) from @tagList.nodes('tags/tag') R(tags)


SELECT DISTINCT documentid
FROM {TABLE}
WHERE tag in
(
SELECT tags.value('.','varchar(20)') 
FROM @tagList.nodes('tags/tag') R(tags)
}
group by id 
having count( distinct tag) >= @tagCount 
END

结尾

于 2009-07-29T20:02:00.627 回答