2015-01-12 159 views
-1

這對我來說是一個有趣的轉折,我通過左連接/空檢查通常解決了舊的「在另一個表中發現不匹配的記錄」問題。在我的搜索中,我還沒有在論壇中找到答案。查找第二個表中的記錄不在第一個

我有一個表A和一個表B,每個表都有相同的字段A和B. A是一個字符串,B是一個整數。

+-------------------+ +-------------------+ 
|  Table A  | |  Table B  | 
| Field A | Field B | | Field A | Field B | 
+---------+---------+ +---------+---------+ 
| A | 1 | | B | 1 | 
| A | 2 | | B | 2 | 
+---------+---------+ | B | 3 | 
         | B | 4 | 
         +---------+---------+ 

所以我需要運行查詢產生一個結果列表如下所示:

+-------------------+ 
|  Table A  | 
| Field A | Field B | 
+---------+---------+ 
| A | 3 | 
| A | 4 | 
+---------+---------+ 

我可以使用左/右連接表清楚地分隔的值(2,3,4) A從B;然而,當我使用純集操作在表B中有表A中沒有匹配的記錄時,如何從表A中獲取字段A正在掙扎。例如,下面的代碼讓我獲得了所有的FieldB,但是FieldA爲null。

SELECT 
    TableA.FieldA 
    ,TableB.FieldB 
FROM 
    TableA 
    RIGHT JOIN TableB ON TableA.FieldB = TableB.FieldB 

重要的是,我有這樣的使用一組操作來執行,所以沒有WHILE構建體,經由插入中間/臨時表等

我明白任何指導/建議。

謝謝!

更新:

感謝您的快速發佈。一些人在內部聯接中提到使用<>。我最初在幾次測試中做到了這一點,並獲得了表格的笛卡爾積,結果是大量的記錄。我離開了這個解決方案大約2個小時。這些帖子重新點燃了火災。

所以我再次刺穿它並向查詢添加了一個GROUP BY子句。但是,由於某種原因,我仍然看到有相似之處的記錄。所以,我必須刪除兩張表有共同記錄的記錄。最終的SQL如下:

SELECT 
    FieldA 
    ,FieldB 
FROM 
    TableA 
    INNER JOIN TableB ON TableA.FieldB <> TableB.FieldB 
WHERE 
    FieldB NOT IN (SELECT TableB.FieldB FROM TableB INNER JOIN TableA ON TableA.FieldB = TableB.FieldB) 
GROUP BY 
    FieldA 
    ,FieldB 

這似乎是工作好了... ...

更新#2:

下面是與實際的表結構的另一個更新的我原來的職位似乎是不清楚。請注意,我可以使用此代碼重新創建我描述的問題的確切發生和解決方案:如果您運行在此表只是一個交叉連接

CREATE TABLE #tblControlData 
(
    fldCN int 
); 

CREATE TABLE #tblCompData 
(
    fldCompanyID int 
    ,fldCN int 
); 

INSERT INTO #tblControlData (fldCN) VALUES(1); 
INSERT INTO #tblControlData (fldCN) VALUES(2); 
INSERT INTO #tblControlData (fldCN) VALUES(3); 
INSERT INTO #tblControlData (fldCN) VALUES(4); 
INSERT INTO #tblControlData (fldCN) VALUES(5); 
INSERT INTO #tblControlData (fldCN) VALUES(6); 
INSERT INTO #tblControlData (fldCN) VALUES(7); 
INSERT INTO #tblControlData (fldCN) VALUES(8); 
INSERT INTO #tblControlData (fldCN) VALUES(9); 

INSERT INTO #tblCompData (fldCompanyID,fldCN) VALUES(34,1); 
INSERT INTO #tblCompData (fldCompanyID,fldCN) VALUES(34,2); 
INSERT INTO #tblCompData (fldCompanyID,fldCN) VALUES(34,3); 

SELECT 
    #tblCompData.fldCompanyID 
    ,#tblControlData.fldCN 
FROM 
    #tblCompData 
    CROSS JOIN #tblControlData 
WHERE 
    #tblControlData.fldCN NOT IN (SELECT fldCN FROM #tblCompData) 
GROUP BY 
    #tblCompData.fldCompanyID 
    ,#tblControlData.fldCN 

DROP TABLE #tblControlData 
DROP TABLE #tblCompData 

,你得到的笛卡爾乘積,這是不正確的。所以然後添加GROUP BY,它仍然是不正確的。然後用NOT IN減去公共項目,這是正確的。

結果如下:

fldCompanyID fldCN 
34    4 
34    5 
34    6 
34    7 
34    8 
34    9 

我一直在這一段時間,我的心是油炸的,但如果你們都看到了一個更好的辦法,我很開放的建議。

謝謝!

+0

只要在比較兩個表的字段B時添加不相等。 –

+0

感謝您的建議 - 請參閱上面的解決方案。 –

+0

請確保您包含問題中的所有情況以及下一個問題的實際預期結果。 @Mike P. –

回答

0

最終的SQL如下:

SELECT 
    FieldA 
    ,FieldB 
FROM 
    TableA 
    INNER JOIN TableB ON TableA.FieldB <> TableB.FieldB 
WHERE 
    FieldB NOT IN (SELECT TableB.FieldB FROM TableB INNER JOIN TableA ON TableA.FieldB = TableB.FieldB) 
GROUP BY 
    FieldA 
    ,FieldB 

這是一個小更緊湊...

SELECT 
    #tblCompData.fldCompanyID 
    ,#tblControlData.fldCN 
FROM 
    #tblCompData 
    CROSS JOIN #tblControlData 
WHERE 
    #tblControlData.fldCN NOT IN (SELECT fldCN FROM #tblCompData) 
GROUP BY 
    #tblCompData.fldCompanyID 
    ,#tblControlData.fldCN 

令人讚歎清晰度有點睡眠提供...

以下的答案必須運行更快...

CREATE TABLE #tblControlData 
(
    fldCN int 
); 

CREATE TABLE #tblCompData 
(
    fldCompanyID int 
    ,fldCN int 
); 

INSERT INTO #tblControlData (fldCN) VALUES(1); 
INSERT INTO #tblControlData (fldCN) VALUES(2); 
INSERT INTO #tblControlData (fldCN) VALUES(3); 
INSERT INTO #tblControlData (fldCN) VALUES(4); 
INSERT INTO #tblControlData (fldCN) VALUES(5); 
INSERT INTO #tblControlData (fldCN) VALUES(6); 
INSERT INTO #tblControlData (fldCN) VALUES(7); 
INSERT INTO #tblControlData (fldCN) VALUES(8); 
INSERT INTO #tblControlData (fldCN) VALUES(9); 

INSERT INTO #tblCompData (fldCompanyID,fldCN) VALUES(34,1); 
INSERT INTO #tblCompData (fldCompanyID,fldCN) VALUES(34,2); 
INSERT INTO #tblCompData (fldCompanyID,fldCN) VALUES(34,9); 

SELECT 
    #tblInterim.fldCompanyID 
    ,#tblInterim.fldControlCN 
FROM 
(
    SELECT 
     #tblCompData.fldCompanyID 
     ,#tblTemp.fldCN AS fldControlCN 
    FROM 
     #tblCompData 
     CROSS APPLY 
     (
     SELECT 
      fldCN 
     FROM 
      #tblControlData 
    ) AS #tblTemp 
    GROUP BY 
     #tblCompData.fldCompanyID 
     ,#tblTemp.fldCN 
) AS #tblInterim 
WHERE 
    #tblInterim.fldControlCN NOT IN (SELECT fldCN FROM #tblCompData WHERE  #tblInterim.fldCompanyID = #tblCompData.fldCompanyID) 
GROUP BY 
    #tblInterim.fldCompanyID 
    ,#tblInterim.fldControlCN 

DROP TABLE #tblControlData 
DROP TABLE #tblCompData 
+0

爲什麼你需要一個NOT IN呢?看起來這個查詢看起來很複雜並且耗時。 @Mike P. –

+0

我想知道Sarath也一樣。我希望我知道。當「NOT IN」存在時,查詢返回正確的數據集,但是當「NOT IN」丟失時不會返回正確的數據集。這在幾個小時前對我來說似乎很奇怪,這就是爲什麼我首先從內連接上的<>移開的原因。 –

+1

我認爲需求並不清楚,或者你無法解釋真實的數據情況。看起來你有很高的成功慾望輸出。這可能會與實際樣本數據產生適得其反的結果。 – KumarHarsh

0

試樣臺

SELECT * INTO A 
FROM 
(
SELECT 'A' [Field A] ,1 [Field B] 
)TAB  


SELECT * INTO B 
FROM 
(
SELECT 'B' [Field A] ,1 [Field B] 
UNION ALL 
SELECT 'B' [Field A] ,2 [Field B] 
UNION ALL 
SELECT 'B' [Field A] ,3 [Field B] 
UNION ALL 
SELECT 'B' [Field A] ,4 [Field B] 
)TAB 

QUERY

SELECT A.[Field A],B.[Field B] 
FROM A 
CROSS JOIN B 
WHERE A.[Field B]<>B.[Field B] 
+0

感謝您的建議 - 請參閱上面的解決方案。 –

+0

我很欣賞這個建議,但是這個解決方案並不適用於表A中的多個記錄。在你的小提琴中添加第二個記錄到表A.它打破了(我相信事實是我的原始文章可能有點不清楚) 。 –

相關問題