Sql 将argument1上的两个表连接到argument2

Sql 将argument1上的两个表连接到argument2,sql,sql-server,Sql,Sql Server,表A包含一个NVARCHAR(200)notnull列Name。其字段由公司名称和下划线组成,并以公司id结尾,例如: 我公司102 表B的PK是一个名为CompanyID的INT NOT NULL列,将包含例如102 我的查询是将这两个表(其中一个参数以另一个参数结尾)进行内部联接,不会产生任何结果。如果有人怀疑显而易见的事实:是的,有匹配的记录 SELECT * FROM [SERVER1].[DB1].[dbo].[TABLE_A] a INNER JOIN [SERVER2].[DB2]

表A包含一个
NVARCHAR(200)notnull
Name
。其字段由公司名称和下划线组成,并以公司id结尾,例如:

我公司102

表B的PK是一个名为
CompanyID
INT NOT NULL
列,将包含例如
102

我的查询是将这两个表(其中一个参数以另一个参数结尾)进行内部联接,不会产生任何结果。如果有人怀疑显而易见的事实:是的,有匹配的记录

SELECT * FROM [SERVER1].[DB1].[dbo].[TABLE_A] a
INNER JOIN [SERVER2].[DB2].[dbo].[TABLE_B] b
ON a.Name LIKE '%[_]' + CONVERT(NVARCHAR, b.CompanyID)
任何关于我的查询为何无法工作的更正和见解都是非常受欢迎的

编辑:公司名称可以在任何地方包含数字和/或下划线,我只想锁定可能最后出现的下划线,后跟任意自然整数。据我所知,可能是_1,也可能是_205952。数字后缀中没有前导零

Like '%[_]' +  Cast(b.CompanyID as Varchar(100))

你要做的就是从名字中去掉这个ID,然后像这里一样加入它

SELECT * FROM [SERVER1].[dbo].[TABLE_A] a
INNER JOIN [SERVER2].[dbo].[TABLE_B] b
cast(right(a.NAME, len(a.NAME)-charindex('_',A.NAME)) as int) = b.CompanyID

您的问题可能是公司名称后面有空格。报告指出:

LIKE支持ASCII模式匹配和Unicode模式匹配。 当所有参数(匹配表达式、模式和转义字符)匹配时, 如果存在)是ASCII字符数据类型,则使用ASCII模式匹配 表演。如果任何一个参数是Unicode数据类型,则所有 参数转换为Unicode,Unicode模式匹配为 表演。使用Unicode数据时(nchar或nvarchar数据类型) 对于LIKE,尾随空格是重要的;但是,对于非Unicode 数据,尾随空格不重要。类Unicode是兼容的 符合ISO标准。类ASCII与早期版本兼容 SQL Server的应用程序

这只是一种可能性。请注意,在
convert()
中使用
varchar
nvarchar
时,应始终包括长度。这对你没有影响

我认为你比较好:

cast(SUBSTRING(a.name, charindex('_', a.name)+1, LEN(a.name)) as int) = b.CompanyId

通过在
CompanyId
上使用相等联接,您有机会在该列上使用索引。

这可能会有帮助:

SELECT * FROM [SERVER1].[dbo].[TABLE_A] a
INNER JOIN [SERVER2].[dbo].[TABLE_B] b
ON a.Name LIKE N'%[_]' + CONVERT(NVARCHAR, b.CompanyID)

我已经测试了你的代码,它对我来说非常有效。唯一可能的原因是没有匹配的记录。

有些地方可能不像您所认为的那样,因为此页面上的大多数代码(包括您的)都应该可以工作,或者至少返回一些内容

SELECT * FROM [SERVER1].[DB1].[dbo].[TABLE_A] a
INNER JOIN [SERVER2].[DB2].[dbo].[TABLE_B] b
ON a.Name LIKE '%[_]' + CONVERT(NVARCHAR, b.CompanyID)
我建议将这些表选择到本地临时表中(允许您检查数据类型/长度),运行
ltrim(rtrim(…)
,即使您认为不需要,也可以使用
N
将文字标记为unicode,显式设置字符串的宽度,任何可以增加简单性或安全性的东西都可以帮助您发现问题

拔头发的人通常以拍头者告终

SELECT Name INTO #TABLE_A FROM [SERVER1].[dbo].[TABLE_A];

SELECT CompanyID INTO #TABLE_B FROM [SERVER1].[dbo].[TABLE_B];

-- Now you can check to see that the columns above are what you believe,
-- and then run your select or any of the selects that have been offered.

SELECT a.Name, b.CompanyID
FROM #TABLE_A AS a
    INNER JOIN #TABLE_B AS b
        ON LTRIM(RTRIM(a.Name)) LIKE N'%[_]' + CAST(b.CompanyID AS NVARCHAR(11))

而且,
[SERVER1].[dbo].[TABLE_A]
对于服务器来说看起来很奇怪。你是说
[DB1].[dbo].[TABLE_A]
还是
[SERVER1].[DB1].[dbo].[TABLE_A]
呢?

为什么不像“%\code>那样转换(NVARCHAR,b.CompanyID)?我不理解
[]
的用法(尽管我从未对连接做过类似的操作:))下划线是文字,不是没有方括号的通配符,下划线是一个单字符通配符,百分号是多字符通配符。那不行。我自己实现了下划线,以允许公司名称本身可能以数字结尾。没有乐趣,我有以数字结尾的公司名称。我得到了结果,但结果不对。嗯。。。“将nvarchar值'MYCOMPANY'转换为数据类型int时,转换失败。”然后,可能数据不一致,如始终公司名称\u编号。也许有数据看起来像是“最大的公司”?这是可能的。我只寻找最后一个下划线,后跟任意的自然整数。如果是这样的话,就用这个来代替。选择*从公司A内部连接拉链b(反向(左(反向(A.name),charindex('',反向(A.name))-1))作为int)=b.CompanyIDclever,但仍然不完全正确。“传递给LEFT或SUBSTRING函数的长度参数无效。”另请注意:值总是在insert@WimOmbelets . . . 你能在数字中有前导0吗?
LEN(a.Name)
应该是
LEN(a.Name)-CHARINDEX(“a.Name”)
@WimOmbelets。你对长度的计算在技术上更精确。但是,如果length参数大于字符串的长度,它只会将字符带到字符串的末尾,因此在这种情况下,精度没有什么区别。我明白了。由于SQL不是我的强项,我在阅读所有这些答案时学到了很多。无论如何,谢谢你的意见。问题解决了。