我有一个名为文档的表,其中一行名为Nigel Harding
DOCUMENTS
id | label
24 | Nigel Harding
他已被另外两个文件标记,其中ID为1&该表称为文档标签
DOCUMENT_TAGS
id | label | Document_id
1 | TAG A | 24
12 | TAG B | 24
我正在尝试创建一个查询,我可以找到一个结果,如果搜索标签 1和12 ,Nigel Harding将出现一次,但我没有运气。
我想出了搜索一个标签ID的查询,但我正在尝试对这两个标签进行查询。
SELECT documents.id
FROM documents
LEFT JOIN documents_tags
ON documents.id=documents_tags.document_id
WHERE documents_tags.tag_id = 1 ORDER BY documents.label
我理解为什么要添加......
AND documents_tags.tag_id = 12
...到最后将无法工作,但我不知道我需要做什么让正确的查询显示我的一个结果,因为我对SQL的理解是非常基本的。
答案 0 :(得分:2)
如果我理解了您的问题,那么您就缺少IN
和DISTINCT
:
SELECT DISTINCT documents.id
FROM documents
LEFT JOIN documents_tags
ON documents.id=documents_tags.document_id
WHERE documents_tags.tag_id IN (1, 12) ORDER BY documents.label
使用IN
,您将获得指定的任何标记ID的文档,并使用DISTINCT
确保每个文档ID只能获取一次。
编辑:由于您是通过documents.label订购的,我猜这是您想要显示的内容。不要忘记您可以将SELECT
声明更改为:
SELECT DISTINCT documents.label
甚至是:
SELECT DISTINCT documents.id, documents.label
答案 1 :(得分:1)
我认为解决此类问题最灵活的方法是使用带有having
子句的聚合。这是一个例子:
SELECT dt.document_id
FROM documents_tags dt
GROUP BY dt.document_id
HAVING sum(dt.tag_id = 1) > 0 and
sum(dt.tag_id = 12) > 0;
having
子句中的每个条件都会计算1(或12)的文档标记数,并且仅当找到两者时,过滤器才会通过。您也可以将其写为:
SELECT dt.document_id
FROM documents_tags dt
WHERE dt.tag_id in (1, 12)
GROUP BY dt.document_id
HAVING count(distinct dt.tag_id) = 2;
答案 2 :(得分:1)
实现此目的的另一种方法(调整为按标签标签搜索,我认为这是你的目标,如果不是仅用dt.ID =等替换dt.Label ='etc':
SELECT documents.id
FROM documents d
WHERE
exists (select dt.id from documents_tags dt
where dt.document_id = d.document_id and dt.label = 'TAG A')
AND
exists (select dt.id from documents_tags dt
where dt.document_id = d.document_id and dt.label = 'TAG B')
答案 3 :(得分:0)
一个WHERE
字就足够了:
SELECT documents.id
FROM documents
LEFT JOIN documents_tags
ON documents.id=documents_tags.document_id
WHERE (documents_tags.tag_id = 1 OR documents_tags.tag_id = 12) ORDER BY documents.label
或者,如果您打算使用n个不同的代码并且不想添加OR documents_tags.tag_id = x
,则可以使用IN
运算符
SELECT documents.id
FROM documents
LEFT JOIN documents_tags
ON documents.id=documents_tags.document_id
WHERE documents_tags.tag_id IN(1,12) ORDER BY documents.label
答案 4 :(得分:0)
听起来你在搜索多个文档标签时会尝试聚合结果,所以你应该使用GROUP BY
,用于将多行分组到一行:
SELECT documents.id
FROM documents
LEFT JOIN documents_tags ON documents.id = documents_tags.document_id
WHERE documents_tags.tag_id IN (1, 12)
GROUP BY documents.id
这将为每个与给定标记ID匹配的文档提供一行。并且您可以通过添加到列表而无需太多痛苦来推广到任何标记ID列表。您甚至可以在select语句中添加COUNT(*)
,以找出给定文档匹配的标记ID数量。