SQL IN()查询结果产生不需要的结果

时间:2011-05-06 11:05:03

标签: sql sql-server asp-classic

如果可能,只需要一些帮助来优化此查询。

SELECT * 
FROM 
    E_Associates INNER JOIN E_Tag_Attributes ON E_Tag_Attributes.AssociateID = E_Associates.associateID 
WHERE 
    (TagID IN (524,546)) 
    AND CONTAINS ((AboutMe,WorkingStyle,Approach,MyValues),'werwer') 
    AND IsActive = 1

基本上我有三张桌子......

E_associates这是联系人表名等...

E_Tag_Attributes这是E_tags表与E_associates之间的链接表。

我想只显示TagID

中包含E_Tag_Attributes 524 AND 546条记录的用户

然而,此查询产生的结果包含一个或两个......

很累,希望它简单明了:)

提前致谢。

3 个答案:

答案 0 :(得分:4)

SQL IN()子句将由OR而不是AND组合。

(...) WHERE A IN ( 1, 2, 3 )

相当于

(...) WHERE ( A = 1 OR A = 2 OR A = 3 )

在这种情况下,您必须两次加入同一个表并在连接条件中移动TagID子句:

SELECT * FROM E_Associates EA
  INNER JOIN E_Tag_Attributes J1 ON J1.AssociateID = EA.associateID AND TagId = 524
  INNER JOIN E_Tag_Attributes J2 ON J2.AssociateID = EA.associateID AND TagId = 526
WHERE CONTAINS ((AboutMe,WorkingStyle,Approach,MyValues),'werwer') AND IsActive = 1

我不确定WHERE子句是否会以这种方式工作。如果列在E_Tag_Attributes表中定义,则可能会出现“模糊”列问题。如果是这种情况,只需将子句放在连接条件中并放入J1。或者J2。在需要的地方。

答案 1 :(得分:2)

假设您想要所有拥有标签524和546的员工:

SELECT * FROM E_Associates 
INNER JOIN E_Tag_Attributes e1
  ON e1.AssociateID = E_Associates.associateID 
INNER JOIN E_Tag_Attributes e2
  ON e2.AssociateID = E_Associates.associateID 
WHERE (e1.TagID IN (524)) AND CONTAINS ((AboutMe,WorkingStyle,Approach,MyValues),'werwer') 
AND (e2.TagID IN (546)) AND CONTAINS ((AboutMe,WorkingStyle,Approach,MyValues),'werwer') 
AND IsActive = 1

答案 2 :(得分:1)

使用指定的IN()子句,它应该查找具有任何一个指定值的记录。所以它会做你所描述的。

如果您只想找到两者指定值的相关记录的那些,您需要在连接中进行。

您可以将TagId字段添加到联接的ON子句中,与WHERE子句中的相同;只是因为它在ON子句中,它没有来指定直接链接到主表的字段。但是在这种情况下,在这里使用IN()将具有与WHERE子句中相同的效果,因此我们需要更进一步......

为了找到链接到每个E_Associates记录的值的两个,您需要加入E_Tag_Attributes表两次:

SELECT * FROM E_Associates
  INNER JOIN E_Tag_Attributes ta1 ON ta1.AssociateID = E_Associates.associateID AND ta1.TagId = 524
  INNER JOIN E_Tag_Attributes ta2 ON ta2.AssociateID = E_Associates.associateID AND ta2.TagId = 526
WHERE CONTAINS ((AboutMe,WorkingStyle,Approach,MyValues),'werwer') AND IsActive = 1

请注意,我必须为两个ta1联接添加别名(ta2E_Tag_Attributes),以防止查询中出现歧义,因为两个表的名称相同

您可能需要考虑的另一个选项是使用IN()进行查询,但要使用GROUP BY AssociateID,并添加WHERE子句COUNT(TagId)=2。这将过滤结果,以便只包含结果集中包含两个标记的结果。