在第二 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
这对我来说是一个有趣的转折,解决了通常用左 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