如果没有 B 则查询 A

Tho*_*lik 3 db2 subquery

我有一个包含列ID, TYPE, DATE, ... 的表,我需要所有数据集TYPE <> 'A'(案例 1),TYPE = A如果没有TYPE = B相同的数据集ID(案例 2)。第一种情况很容易,所以我想UNION用来结合第一种和第二种情况。但我不知道如何选择第二种情况。我正在尝试自我连接,例如:

SELECT *
FROM MY_TABLE TAB1
JOIN MY_TABLE TAB2
ON
  TAB1.ID = TAB2.ID
  AND TAB1.TYPE = 'A'
  AND TAB2.TYPE = 'B'
Run Code Online (Sandbox Code Playgroud)

这样我就得到了我不想要的集合。我想我需要一个子查询,但我不知道我应该朝哪个方向工作。

也许是这样的:

SELECT *
FROM MY_TABLE TAB1
WHERE TAB1.TYPE <>'A'
UNION
SELECT *
FROM MY_TABLE TAB1
NOT IN
(SELECT *
FROM MY_TABLE TAB1
JOIN MY_TABLE TAB2
ON
  TAB1.ID = TAB2.ID
  AND TAB1.TYPE = 'A'
  AND TAB2.TYPE = 'B')
Run Code Online (Sandbox Code Playgroud)

例子:

ID | TYPE | ...
---------------
1  |  B   | ...
2  |  A   | ...
2  |  B   | ...
3  |  A   | ...
Run Code Online (Sandbox Code Playgroud)

我需要第 1 行(TYPE <> 'A')、第 3 行(TYPE <> 'A')和第 4 行(没有相同 ID 和 TYPE = 'B' 的集合)。我不想要第 2 行,因为 TYPE = 'A' 并且有一个具有相同 ID 和 TYPE = 'B' 的数据集。所以结果应该是:

ID | TYPE | ...
---------------
1  |  B   | ...
2  |  B   | ...
3  |  A   | ...
Run Code Online (Sandbox Code Playgroud)

Sco*_*red 6

使用NOT EXISTS

Declare @T table (id int, [type] varchar(5))
insert into @t(id,[type]) values(1,'B'),(2,'A'),(2,'B'),(3,'A')

SELECT *
FROM @T TAB1
WHERE [TYPE] <> 'A'

UNION ALL

SELECT *
FROM @t TAB1
WHERE [type] = 'A'
    AND NOT EXISTS (
        SELECT *
        FROM @t
        WHERE id = TAB1.id
            AND [type] = 'B'
        )
Run Code Online (Sandbox Code Playgroud)

以上使用UNION ALL(简单串联),这通常比重复删除更有效UNION [DISTINCT]。两个集合,一个 withtype = A另一个 withtype <> A不可能重叠,所以连接在这里是安全的。

可以将逻辑表达为WHERE [TYPE] <> 'A' OR ([TYPE] = 'A' AND NOT EXISTS ...)但检查哪种方法可以为您提供更好的性能(复杂的析取并不总是优化得很好)。


归档时间:

查看次数:

284 次

最近记录:

7 年,7 月 前