T-SQL - 仅当连接的行满足条件列表时才在 table 中查找不同的值

T-SQL - Find distinct values in table only if joined rows satisfy a list of criterias

这对我来说是满口的。 我面临的挑战之一是我不知道如何提出问题 - 从标题可以看出这一点。

我将尝试说明我的问题:

我有一个table,答:

ID    LocationID
11    185
12    185
13    206

还有一个table B:

ID    AID    Position    Value
1     11     1           4
2     11     3           8
3     11     5           4
4     12     1           4
5     12     2           4
6     12     3           5

Table B 通过 IDAID 关联到 table A。我想构建一个具有以下过滤器的查询: Position = 1 AND Value = 4Position = 3 AND Value = 5,这给了我一个来自 A.ID 的不同 ID 的列表,它稳定了 所有 给定的标准。

我的意思是,如果我通过 INNER JOIN 将两个 table 连接在一起,我只希望有 A.ID = 12.

我自己开始解决这个问题的思路是:

SELECT DISTINCT A.ID
FROM A
    INNER JOIN B ON (A.ID = B.AID)
WHERE
    A.LocationID = 185 AND
    (B.Position = 1 AND B.Value = 4) OR
    (B.Position = 3 AND B.Value = 5)

这显然行不通。我以为我有一个明确的解决方案,但当我想到它时,我真的没有。

我有点被这个问题难住了,我很难寻找解决它的策略,因为我什至不知道在我的搜索中使用什么关键字。

您可以使用 GROUP BYHAVING:

SELECT A.ID
FROM A
    INNER JOIN B ON (A.ID = B.AID)
GROUP BY A.ID
HAVING MAX(CASE WHEN A.LocationID = 185 THEN 1 END) = 1
   AND MAX(CASE WHEN B.Position = 1 AND B.Value = 4 THEN 1 END) = 1 
   AND MAX(CASE WHEN B.Position = 3 AND B.Value = 5 THEN 1 END) = 1

演示:SQL Fiddle

实际上可以将 LocationID 条件移动到 WHERE:

SELECT A.ID
FROM Table1 A
    INNER JOIN Table2 B ON (A.ID = B.AID)
WHERE A.LocationID = 185
GROUP BY A.ID
HAVING MAX(CASE WHEN B.Position = 1 AND B.Value = 4 THEN 1 END) = 1 
   AND MAX(CASE WHEN B.Position = 3 AND B.Value = 5 THEN 1 END) = 1
SELECT DISTINCT A.ID
FROM A
WHERE A.ID IN(
    SELECT ID 
FROM B
WHERE    (B.Position = 1 AND B.Value = 4) OR
    (B.Position = 3 AND B.Value = 5)

)

如果我没理解错的话。

SELECT 不同 A.ID 从一个 内部连接 ​​B ON (A.ID = B.AID) 在哪里 A.LocationID = 185 和 (B.Position = 1 和 B.Value = 4) 或 (B.Position = 3 AND B.Value = 5)

您没有添加括号。

这就是你的执行方式。

(A.LocationID = 185
       AND  ( B.Position = 1
               AND B.Value = 4 ) )
              OR ( B.Position = 3
                   AND B.Value = 5 )  

AND 的优先级高于 OR。试试这个

SELECT DISTINCT A.ID
FROM   A
       INNER JOIN B
               ON ( A.ID = B.AID )
WHERE  A.LocationID = 185
       AND ( ( B.Position = 1
               AND B.Value = 4 )
              OR ( B.Position = 3
                   AND B.Value = 5 ) )