使用连接和多个AND的MySQL查询不太起作用

时间:2011-03-31 13:07:39

标签: mysql

这是我的疑问:

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' )

查询将在第一个ANDtag对之后的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|

所以我真的很困惑为什么我的原始查询不起作用?

3 个答案:

答案 0 :(得分:4)

据我所知,
- dt1.tag不能同时为agentextension 就像
一样 - dt1.value不能同时为excelxls

考虑将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如果文档可以有多个代理和扩展名?)