"WHERE (subquery) IN (subquery)"可以吗?

Is "WHERE (subquery) IN (subquery)" possible?

我们需要 select 只使用连接到机器的标签的测试。

示例:

像这样的构造应该可以工作:

SELECT *
FROM Test te
WHERE 
    (SELECT tt.tagId
    FROM TagTest tt 
    WHERE tt.testId = te.Id)
 IN
    (SELECT tm.tagId
    FROM TagMachine tm
    WHERE tm.machineId = 123)

但是这种查询可能吗?如果没有,怎么可能达到预期的效果?

如果第一个 returns 是标量值(即单行),则此查询是可能的。因此,仅使用 IN 无法实现您想做的事情。一种处理此问题的 Postres 方法使用数组

WHERE (SELECT ARRAY_AGG(tt.tagId)
       FROM TagTest tt 
       WHERE tt.testId = te.Id
      ) <@
      (SELECT ARRAY_AGG(tm.tagId)
       FROM TagMachine tm
       WHERE tm.machineId = 123
      )

IN() 自己做不到。您可以制作两个 CTE 并将它们连接在一起,但这仍然有点棘手。

相反,让我们来扭转这个问题。我们可以查找 缺少任何一个必需标签 的记录,而不是查找匹配 所有 良好标签的记录。从问题的第一个示例([A,B,C] vs [A,B,D])中,我们正在寻找带有 C 标记的 TestTag 记录。一旦我们有了这些信息,我们就可以在子查询中使用它来排除所有 Test 记录,其中 Id 出现在这些结果中。

所以首先要做的是使用排除连接来查找缺少相应 TagMachine 记录的 TestTag 结果:

SELECT tt.testId, tt.tagId
FROM TestTag tt 
LEFT JOIN TagMachine tm ON tm.machineId = 123 AND tm.tagId = tt.tagId
WHERE tm.tagId IS NULL

上述查询结果中任何 testId 的存在使得 TestId 不合格 ... 但是我们确实需要 所有其他 Test 记录。所以现在只需将其限制为 DISTINCT testId 并将其用作任何排除连接、NOT IN() 或 NOT EXISTS() 中的子查询。随你挑:

SELECT * 
FROM Tests
WHERE Id NOT IN (
     --identify tests hat are missing at least one tag
     SELECT DISTINCT tt.testId 
     FROM TestTag tt 
     LEFT JOIN TagMachine tm ON tm.machineId = 123 AND tm.tagId = tt.tagId
     WHERE tm.tagId IS NULL)