Db2
如果沒有B,則查詢A
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] <> '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 <> A
不可能重疊,所以在這裡串聯是安全的。您也可以將邏輯表達為
WHERE [TYPE] <> 'A' OR ([TYPE] = 'A' AND NOT EXISTS ...)
但檢查哪種方法可以提供更好的性能(複雜的析取並不總是能很好地優化)。