这是我的疑问:
SELECT dt1.*, document.*
FROM documenttags dt1
LEFT JOIN document ON dt1.id = document.id
WHERE
(dt1.tag = 'agent' AND dt1.value = 'excel' )
AND
(dt1.tag = 'extension' AND dt1.value = 'xls' )
查询将在第一个AND
和tag
对之后的value
之前正常工作:
SELECT dt1.*, document.*
FROM documenttags dt1
LEFT JOIN document ON dt1.id = document.id
WHERE (dt1.tag = 'agent' AND dt1.value = 'excel' )
第二个查询的典型结果是:
id | tag | value | ...rest of columns'
'11 | agent | excel | ... rest of columns
最后,搜索id=11
会产生:
id | tag | value |
11 | agent | excel |
11 | extension| xls|
所以我真的很困惑为什么我的原始查询不起作用?
答案 0 :(得分:4)
据我所知,
- dt1.tag
不能同时为agent
和extension
就像
一样
- dt1.value
不能同时为excel
和xls
。
考虑将AND
更改为OR
。
SELECT dt1.*, document.*
FROM documenttags dt1
LEFT JOIN document ON dt1.id = document.id
WHERE
(dt1.tag = 'agent' AND dt1.value = 'excel' )
OR -- it was an AND previously
(dt1.tag = 'extension' AND dt1.value = 'xls' )
答案 1 :(得分:3)
你可能从一开始就意味着这个,但我没有得到它。
你想要的(我现在想的)是关联(表格中的行)document
与 2或更多(来自)documenttags
的行。这可以通过从表格文档到文档标记的2个或更多JOIN
来实现,如下所示。
如果您有3个条件,则需要3个JOIN
等等。
以下查询将为您提供所有excel
标记为agent
,和 xls
标记为extension
的文档:
(旁注:是的,你是对的,“和”是这里使用的正确术语!)
SELECT dt1.*
, dt2.*
, document.*
FROM document
JOIN documenttags dt1
ON dt1.id = document.id
JOIN documenttags dt2
ON dt2.id = document.id
WHERE
(dt1.tag = 'agent' AND dt1.value = 'excel' )
AND
(dt2.tag = 'extension' AND dt2.value = 'xls' )
这也会奏效。使用一个JOIN和一个分组:
SELECT document.*
, COUNT(document.id) AS filtersPassed
FROM document
JOIN documenttags dt
ON dt.id = document.id
--filters (conditions) go here:
WHERE (dt.tag = 'agent' AND dt.value = 'excel')
OR (dt.tag = 'extension' AND dt.value = 'xls')
GROUP BY document.id
HAVING filtersPassed = 2 --number of filters
在此处使用OR
,因为查询的工作原理如下:
对于每个文档,它会检查所有相关行并根据您的条件保留这些行。我们不能在这里使用AND
,因为每一行都是逐个检查的,当然一行不能有两个标签,只有一个。因此,我们保留所有好的标签然后我们将它们组合在一起并计算每个文档的数量(分组是计算SQL中行的常用方法。)然后我们只需保留通过两个过滤器的文档({{1 }})。
第二个查询的优点是可以用于更复杂的查询,例如,如果您有4个过滤器,并且您想查找通过这些过滤器中的3个或4个的文档。只需输入4个条件(= 2
s)和OR
。
答案 2 :(得分:1)
我认为,如果可能的话,您应该考虑更改架构。
为什么不直接将代理商和扩展程序字段添加到文档表(或相关的特定表格,例如{{1} }和document_agent
如果文档可以有多个代理和扩展名?)