0

我在制定查询时遇到了一些麻烦,想知道是否有人可以提供帮助。我在这里将表格信息简化到最低限度,以尝试让我更容易理解我正在尝试做的事情。我有两个表 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 返回而言,这正是我想要的,但是我需要能够返回匹配的值。因此,如果有一个 A 的值为 X,另一个 A 的值为 Y,我希望 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 似乎不太合适。如果有人能理解我正在尝试做的事情并指出我正确的方向,那将不胜感激。谢谢!

4

1 回答 1

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如果不止一行匹配,您想要最低的列。

于 2013-04-04T19:24:07.933 回答