我的INNER JOIN过滤掉了太多,或者我看不出有什么区别。
我正在尝试在同一台服务器上合并来自2个不同数据库的2个表。
我的第一步是找到匹配的所有值:
SELECT intl.*
FROM tblData intl
INNER JOIN [db].dbo.tblData us
ON intl.DataID = us.DataID
AND intl.AnotherID = us.AnotherID
AND intl.DataValue = us.DataValue
AND intl.TextValue = us.TextValue
AND intl.DefaultValue = us.DefaultValue
AND intl.RateValue = us.RateValue
AND intl.YetAnotherID = us.YetAnotherID
我检查了所有列,它们是相同类型和相同的varchar值。所以这个查询应该带回所有匹配的值。
然而......事实并非如此。它只返回200多条记录,如果我在将200多条记录插入临时表后运行此查询:
SELECT intl.DataID
FROM tblData intl
LEFT JOIN TempDataTable TDT
ON TDT.DataID = intl.DataID
AND TDT.AnotherID = intl.AnotherID
AND TDT.DataValue = intl.DataValue
AND TDT.TextValue = intl.TextValue
AND TDT.DefaultValue = intl.DefaultValue
AND TDT.RateValue = intl.RateValue
AND TDT.YetAnotherID = intl.YetAnotherID
WHERE TDT.DataID IS NULL
此查询返回1500多行。
我对美国数据运行了类似的查询,发现了相同的差异(返回了1500多行)。
我看了1条记录只是为了看看我能辨别出什么东西,我发现每张桌子(INTL和US)的记录完全相同!
DataID: 1
AnotherID: 1
DataValue: NULL
TextValue: NORMAL
DefaultValue: 0
RateValue: NULL
YetAnotherID: 1
我想我的内部联接在结构上找到了两个表之间的差异,但我看不到它。
关于导致这种情况的任何想法?
答案 0 :(得分:2)
这可能是由于您在LEFT JOIN
的等式检查失败后表中的NULL
值造成的。
NULL
值不等于任何值,甚至不等于同一数据类型的另一个ON
。
要解决此问题,除了现有的NULL
条件之外,您还可以在JOIN
子句中添加SELECT intl.DataID
FROM tblData intl
LEFT JOIN TempDataTable TDT
ON (
(TDT.DataID IS NULL AND intl.DataID IS NULL)
OR TDT.DataId = intl.DataId
)
AND (
(TDT.AnotherID IS NULL AND intl.AnotherID IS NULL)
OR TDT.AnotherId = intl.AnotherId
)
AND (
(TDT.DataValue IS NULL AND intl.DataValue IS NULL)
OR TDT.DataValue = intl.DataValue
)
AND (
(TDT.TextValue IS NULL AND intl.TextValue IS NULL)
OR TDT.TextValue = intl.TextValue
)
AND (
(TDT.DefaultValue IS NULL AND intl.DefaultValue IS NULL)
OR TDT.DefaultValue = intl.DefaultValue
)
AND (
(TDT.RateValue IS NULL AND intl.RateValue IS NULL)
OR TDT.RateValue = intl.RateValue
)
AND (
(TDT.YetAnotherID IS NULL AND intl.YetAnotherID IS NULL)
OR TDT.YetAnotherID = intl.YetAnotherID
)
WHERE TDT.DataID IS NULL
子句,以检查双方的{{1}}值:
{{1}}
答案 1 :(得分:2)
我喜欢这种处理NULL
平等比较的方法。
SELECT intl.*
FROM tblData intl
INNER JOIN [db].dbo.tblData us
ON EXISTS (SELECT intl.DataID,
intl.AnotherID,
intl.DataValue,
intl.TextValue,
intl.DefaultValue,
intl.RateValue,
intl.YetAnotherID,
INTERSECT
SELECT us.DataID,
us.AnotherID,
us.DataValue,
us.TextValue,
us.DefaultValue,
us.RateValue,
us.YetAnotherID)
答案 2 :(得分:2)
Values null not take in your query. Use isnull(value, 0) for type value number and isnull(value, '') for type value chararctere
SELECT intl.DataID
FROM tblData intl
inner JOIN TempDataTable TDT
ON isnull(TDT.DataID, 0) = isnull(intl.DataID, 0)
AND isnull(TDT.AnotherID, 0) = isnull(intl.AnotherID, 0)
AND isnull(TDT.DataValue, '') = isnull(intl.DataValue, '')
AND isnull(TDT.TextValue, '') = isnull(intl.TextValue, '')
AND isnull(TDT.DefaultValue, 0) = isnull(intl.DefaultValue, 0)
AND isnull(TDT.RateValue, '') = isnull(intl.RateValue, '')
AND isnull(TDT.YetAnotherID, 0) = isnull(intl.YetAnotherID, 0)
答案 3 :(得分:1)
你INNER JOIN
正在做它应该做的事情,那就是从tblData(us)和tblData(国际)返回仅行,其中你的tdt 全部 =国际条约适用。如果它是NULL
值,则coalesce()
将是您要使用的值。考虑一下:
select 1 where null = null
select 2 where coalesce(null,2) = coalesce(null,2)
答案 4 :(得分:1)
EXISTS可能对此查询有用。
SELECT
intl.DataID
FROM
tblData intl
WHERE
NOT EXIST
(
SELECT TOP 1 FROM TempDataTable TDT
WHERE
TDT.DataID = intl.DataID AND
TDT.AnotherID = intl.AnotherID AND
TDT.DataValue = intl.DataValue AND
TDT.TextValue = intl.TextValue AND
TDT.DefaultValue = intl.DefaultValue AND
TDT.RateValue = intl.RateValue AND
TDT.YetAnotherID = intl.YetAnotherID
)