完全外部连接不匹配
Full Outer Join Mismatching
Microsoft SQL 服务器中此类请求的新功能。我在两个 table 上使用完全外部联接来查找在右侧 table(新)与左侧 table(旧)中不匹配的记录。我试图从新的 table 中找到新的乐谱,这样我就可以用最新的乐谱更新作品 table,同时仍然保留尚未更新的旧乐谱。这是我的设置
Select
a.customer
,a.date
,a.Cat score
,a.Dog score
,a.Mouse score
,b.customer
,b.date
,b.Cat score
,b.Dog score
,b.Mouse score
From Old Table a
Full Outer Join New Table b
ON a.customer = b.customer
AND a.date = b.date
AND a.Cat score = Cast(b.Cat score as Varchar)
AND a.Dog score = Cast(b.Dog score as Varchar)
AND a.Mouse score = Cast(b.Mouse score as Varchar)
注意 --- 必须将分数转换为 Varchar,否则我无法使连接正常工作。 "Conversion failed when converting the varchar value '9.0000' to data type int."
结果:
两个列表 100% 不同,没有任何匹配项
这不可能是真的,因为我可以手动搜索两个 table 中的记录,并在两个 table 中找到完全相同的结果。也许有更好的方法来进行此类更新?
你的问题是字符串 9 和 9.0000 不相等。他们不加入。这些 table 变量将用于演示:
DECLARE @TableA TABLE
(
CatScore Int
)
;
DECLARE @TableB TABLE
(
CatScore VARCHAR(10)
)
;
INSERT INTO @TableA (CatScore) VALUES (9);
INSERT INTO @TableB (CatScore) VALUES ('9.0000');
第一个例子强调了不匹配。
不匹配的连接示例
SELECT
*
FROM
@TableA AS a
FULL OUTER JOIN @TableB AS b ON b.CatScore = CAST(a.CatScore AS VARCHAR(50))
返回值
CatScore CatScore
9 NULL
NULL 9.0000
您需要做的是匹配数据类型,然后匹配值。此示例假设:
- Table A 将猫分数存储为整数。
- Table B 存储与 varchar 相同的内容。
- Table B 在句点后总是包含 4 个零。
匹配示例
SELECT
*
FROM
@TableA AS a
FULL OUTER JOIN @TableB AS b ON b.CatScore = CAST(a.CatScore AS VARCHAR(50)) + '.0000'
Returns
CatScore CatScore
9 9.0000
此处整数 9 已转换为 varchar。然后添加了句点和尾随零。这不是小数位,因为这些不是真正的数字。
从这个练习中得到的教训是;始终使用正确的数据类型。将数字存储在字符串中会进一步导致问题。
更新
将两个字段都转换为 DECIMAL 会更有意义。包含数字类数据的整数和 varchar 都可以转换为小数。在为匹配投射字段时,您希望找到最小的 data type 来保存来自两个源字段的所有输入。
Microsoft SQL 服务器中此类请求的新功能。我在两个 table 上使用完全外部联接来查找在右侧 table(新)与左侧 table(旧)中不匹配的记录。我试图从新的 table 中找到新的乐谱,这样我就可以用最新的乐谱更新作品 table,同时仍然保留尚未更新的旧乐谱。这是我的设置
Select
a.customer
,a.date
,a.Cat score
,a.Dog score
,a.Mouse score
,b.customer
,b.date
,b.Cat score
,b.Dog score
,b.Mouse score
From Old Table a
Full Outer Join New Table b
ON a.customer = b.customer
AND a.date = b.date
AND a.Cat score = Cast(b.Cat score as Varchar)
AND a.Dog score = Cast(b.Dog score as Varchar)
AND a.Mouse score = Cast(b.Mouse score as Varchar)
注意 --- 必须将分数转换为 Varchar,否则我无法使连接正常工作。 "Conversion failed when converting the varchar value '9.0000' to data type int."
结果: 两个列表 100% 不同,没有任何匹配项
这不可能是真的,因为我可以手动搜索两个 table 中的记录,并在两个 table 中找到完全相同的结果。也许有更好的方法来进行此类更新?
你的问题是字符串 9 和 9.0000 不相等。他们不加入。这些 table 变量将用于演示:
DECLARE @TableA TABLE
(
CatScore Int
)
;
DECLARE @TableB TABLE
(
CatScore VARCHAR(10)
)
;
INSERT INTO @TableA (CatScore) VALUES (9);
INSERT INTO @TableB (CatScore) VALUES ('9.0000');
第一个例子强调了不匹配。
不匹配的连接示例
SELECT
*
FROM
@TableA AS a
FULL OUTER JOIN @TableB AS b ON b.CatScore = CAST(a.CatScore AS VARCHAR(50))
返回值
CatScore CatScore
9 NULL
NULL 9.0000
您需要做的是匹配数据类型,然后匹配值。此示例假设:
- Table A 将猫分数存储为整数。
- Table B 存储与 varchar 相同的内容。
- Table B 在句点后总是包含 4 个零。
匹配示例
SELECT
*
FROM
@TableA AS a
FULL OUTER JOIN @TableB AS b ON b.CatScore = CAST(a.CatScore AS VARCHAR(50)) + '.0000'
Returns
CatScore CatScore
9 9.0000
此处整数 9 已转换为 varchar。然后添加了句点和尾随零。这不是小数位,因为这些不是真正的数字。
从这个练习中得到的教训是;始终使用正确的数据类型。将数字存储在字符串中会进一步导致问题。
更新
将两个字段都转换为 DECIMAL 会更有意义。包含数字类数据的整数和 varchar 都可以转换为小数。在为匹配投射字段时,您希望找到最小的 data type 来保存来自两个源字段的所有输入。