在第二 table 中查找记录而不是在第一中

Finding records in second table not in first

这对我来说是一个有趣的转折,解决了通常用左 join/null 检查解决的旧 "find unmatched records in another table" 问题。我在论坛中搜索时没有找到满足我需求的答案。

我有一个 table A 和一个 table 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    |
+---------+---------+

我可以使用 left/right 连接到 table A 和 B 来清楚地将值 (2,3,4) 分开;但是,当我在 Table B 中有记录但在 table A 中使用纯集合操作没有匹配项时,我正在努力解决如何从 Table A 获取字段 A 的问题。例如,以下代码获取了所有 FieldB,但 FieldA 为空。

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

重要的是,我必须使用集合操作来执行此操作,因此没有 WHILE 构造,intermediate/temp tables 通过插入等

我很感激任何 guidance/suggestions。

谢谢!

更新:

感谢您的快速 post。一些人提到在内连接上使用 <>。我最初是在几次测试中这样做的,得到了​​ tables 的笛卡尔积,结果是大量的记录。我离开那个解决方案大约 2 个小时。这些 post 重新点燃了那团火。

所以我又尝试了一下,并在查询中添加了一个 GROUP BY 子句。但是,出于某种原因,我仍然看到有相似之处的记录。因此,我不得不删除两个 table 具有共同记录的记录。最后的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:

这是另一个关于实际 table 结构的更新,因为我原来的 post 似乎不清楚。请注意,我可以重新创建我描述的问题的确切发生以及使用此代码的解决方案:

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

如果您 运行 只是对此 table 进行交叉连接,您将得到笛卡尔积,这是不正确的。于是再加上GROUP BY还是不行。然后用NOT IN减去共同的项就对了

结果如下:

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

我在这上面已经有一段时间了,我的想法很混乱,但如果你们都看到更好的方法,我愿意接受建议。

谢谢!

样本 TABLE

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

查询

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

最后的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