2016-04-14 37 views
2

使用2008 R2。如何在TSQL中查找未配對的行?

我的表應該包含一些配對的行 - 一個取消事務和一個添加事務,但是我們有一些不好的數據,只有一個取消。

我試圖識別這些並消除它們。我嘗試了下面的代碼,但是SQL返回了錯誤「使用UNION,INTERSECT或EXCEPT運算符組合的所有查詢在其目標列表中必須具有相同數量的表達式。」

如何識別這些不匹配的行?

select * 
from dbo.mytable t 
where typename = 'Cancel' 
except 
Select * 
from dbo.mytable t1 
inner join dbo.mytable t2 
    on t1.id = t2.id 
where t1.typename = 'Cancel' 
and t2.typename = 'Add' 

回答

2

你必須在選擇列表中指定id領域:

SELECT id 
FROM mytable 
WHERE typename = 'Cancel' 

EXCEPT 

SELECT id 
FROM mytable 
WHERE typename = 'Add' 

上面的查詢選擇id值,其無與倫比的「取消」記錄存在。

或者您可以使用一個LEFT JOIN

SELECT t1.id 
FROM mytable t1 
LEFT JOIN mytable t2 ON t1.id = t2.id AND t2.typename = 'Add' 
WHERE t1.typename = 'Cancel' AND t2.id IS NULL 
+0

謝謝 - 他們都工作(現在,我爲什麼沒有想到這一點?)。您建議的第一個查詢返回3個不同的行,而第二個查詢返回10個包含重複項的行(在該ID上)。 – DeveloperM

1

試試這個:

select id 
from dbo.mytable t 
where typename = 'Cancel' 
except 
Select id 
from dbo.mytable t1 
inner join dbo.mytable t2 
    on t1.id = t2.id 
where t1.typename = 'Cancel' 
and t2.typename = 'Add' 
+0

謝謝你的迴應。這個查詢花費的時間比@Giorgos Betsos建議的要長得多,在50秒內返回32行(包括那個id的一些模糊),但是當我重複執行時,它的運行速度更快。我想我會繼續他的建議。 – DeveloperM

0
SELECT * 
FROM (
     SELECT *, 
       SUM(CASE typename WHEN 'add' THEN 1 END) OVER (PARTITION BY id) addcnt, 
       SUM(CASE typename WHEN 'cancel' THEN 1 END) OVER (PARTITION BY id) cancelcnt 
     FROM mytable 
     ) q 
WHERE addcnt IS NULL 
     AND cancelcnt > 0 

這將選擇在他們取消所有的交易,但沒有添加,包括其他可能的類型。