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 通过 ID
和 AID
关联到 table A。我想构建一个具有以下过滤器的查询:
Position = 1 AND Value = 4
和 Position = 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 BY
和 HAVING
:
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 ) )
这对我来说是满口的。 我面临的挑战之一是我不知道如何提出问题 - 从标题可以看出这一点。
我将尝试说明我的问题:
我有一个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 通过 ID
和 AID
关联到 table A。我想构建一个具有以下过滤器的查询:
Position = 1 AND Value = 4
和 Position = 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 BY
和 HAVING
:
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 ) )