Db2

如果沒有B,則查詢A

  • January 30, 2018

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'

這樣我就得到了我不想要的集合。我想我需要一個子查詢,但我不知道我應該朝哪個方向工作。

也許是這樣的:

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')

例子:

ID | TYPE | ...
---------------
1  |  B   | ...
2  |  A   | ...
2  |  B   | ...
3  |  A   | ...

我需要第 1 行(TYPE <> ‘A’)、第 3 行(TYPE <> ‘A’)和第 4 行(沒有具有相同 ID 和 TYPE = ‘B’ 的集合)。我不想要第 2 行,因為 TYPE = ‘A’ 並且有一個具有相同 ID 和 TYPE = ‘B’ 的數據集。所以結果應該是:

ID | TYPE | ...
---------------
1  |  B   | ...
2  |  B   | ...
3  |  A   | ...

使用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] &lt;&gt; 'A'

UNION ALL

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

上述使用UNION ALL(簡單連接)通常比重複刪除更有效UNION [DISTINCT]。兩個集合,一個 withtype = A和另一個 withtype &lt;&gt; A不可能重疊,所以在這裡串聯是安全的。

可以將邏輯表達為WHERE [TYPE] &lt;&gt; 'A' OR ([TYPE] = 'A' AND NOT EXISTS ...)但檢查哪種方法可以提供更好的性能(複雜的析取並不總是能很好地優化)。

引用自:https://dba.stackexchange.com/questions/196572