MySQL查询出现问题

时间:2013-04-04 19:00:31

标签: mysql

我在制定查询时遇到了一些麻烦,并且想知道是否有人可以提供帮助。我将表格信息简化为最低限度,以便尝试让我们很容易理解我正在尝试做的事情。 我有两个表A和B.A有一个BId列和一个Value字段。 B具有与问题无关的信息。 我想要做的是返回一组基于任意布尔逻辑的B,它包含一个包含BId并匹配某个值的A。另外,我想返回匹配的值。下面是我在查询中想要的几乎可行的示例:

SELECT * FROM B
    WHERE 
    (
         (
         EXISTS (
             SELECT a1.Value FROM A as a1 WHERE a1.BId = B.Id AND a1.Value = "X"
         ) 
         AND EXISTS (
             SELECT a2.Value FROM A as a2 WHERE a2.BId = B.Id AND a2.Value = "Y"
         )
         )
         OR EXISTS (
             SELECT a3.Value FROM A as a3 WHERE a3.BId = B.Id AND a3.Value = "Z"
         )
);

就B返回而言,这正是我想要的,但是我需要能够返回匹配的值。因此,如果存在具有值X的A和具有值Y的另一个A,则我希望a1和a2具有包含在行中的值X和Y.如果没有值为Z的A,则该行将返回NULL。我不确定这样做的语法或可能性。 我尝试的另一种方法是使用JOIN:

SELECT *, a1.Value, a2.Value FROM B 
    INNER JOIN A AS a1 ON a1.BId = B.Id
    INNER JOIN A AS a2 on a2.BId = B.Id
WHERE 
(
  (
     a1.Value = "X" AND a2.Value = "Y"
  )
  OR 
  (
     a1.Value = "Z"
  )
);

这会正确返回值,但只有在匹配X和Y时才有效。如果Z匹配,因为为了完成第一部分有两个JOIN语句,我得到重复的结果。由于这个原因,我对使用这种方法持怀疑态度。像这样使用JOIN似乎不对。 如果有人能够理解我正在尝试做什么,并指出我正确的方向,将非常感激。谢谢!

1 个答案:

答案 0 :(得分:1)

你可能已经知道了,但我会指出这一点:正如你所说,你的初始SQL查询有效,但你我需要能够返回匹配的值。如何实现这一点没有通用的答案,因为这不是查询的工作方式。 WHERE EXISTS (SELECT...)语法与任何行都不匹配,如果可以找到一个或多个匹配行,则返回TRUE。含义:您的数据库可能有多个行匹配。

如果我查看数据库设计,您的表A似乎有一个外键BId指向B中的记录,并且您没有提及任何唯一键,最可爱的是,至少对于某些值,有多行符合您的条件。

如果您尝试使用JOIN实现相同的效果,首先必须确保只获得与B中的行一样多的结果。 (我的例子中有10个结果)。通常,这是通过使用GROUP BY子句实现的。我还将语法更改为LEFT JOIN,以便分组结果在B中每条记录只返回一行:

SELECT B.Id, MIN(a1.ID) AS MinA1, MIN(a2.ID) AS MinA2, MIN(a3.ID) as MinA3 FROM B
LEFT JOIN A AS a1 ON a1.BId = B.Id AND a1.value='X'
LEFT JOIN A AS a2 on a2.BId = B.Id AND a2.value='Y'
LEFT JOIN A AS a3 ON a3.BId = B.Id AND a3.value='Z'
GROUP BY B.Id

现在最后一部分是添加一个条件,消除那些与你的条件不匹配的结果,这将是:

HAVING (MinA1 IS NOT NULL AND MinA2 IS NOT NULL) OR (MinA3) IS NOT NULL

以上假设您的表格A包含您要检索的Id列,并且如果多个行匹配,您希望得到最低Id