在第二个表中找不到第一个记录

时间:2015-01-12 04:19:33

标签: sql-server

这对我来说是一个有趣的转折,在另一张桌子上找到了无与伦比的记录"通常用左连接/空检查解决的问题。在我的搜索中,我没有在论坛中找到答案。

我有一个表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)与B中的表A隔离;但是,当我在表B中使用纯设置操作在表A中没有匹配的记录时,我正在努力学习如何从表A获得字段A.例如,以下代码获取了FieldB的全部内容,但FieldA为null。

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

重要的是,我必须使用set操作执行此操作,因此没有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

我已经有一段时间了,而且我的思绪已经被炒了,但是如果你们都看到了更好的方式,我会接受建议。

谢谢!

2 个答案:

答案 0 :(得分: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]

答案 1 :(得分: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