Reputation: 5265
TABLE_A contains an NVARCHAR(200) NOT NULL
column Name
. Its fields are made up of company names followed by an underscore and ending in a company id, e.g.:
MYCOMPANY_102
TABLE_B's PK is an INT NOT NULL
column called CompanyID
and would contain e.g. 102
My query, to inner join these two tables where one argument ends with the other, yields no results. In case anyone wonders the obvious: yes, there are matching records.
SELECT * FROM [SERVER1].[DB1].[dbo].[TABLE_A] a
INNER JOIN [SERVER2].[DB2].[dbo].[TABLE_B] b
ON a.Name LIKE '%[_]' + CONVERT(NVARCHAR, b.CompanyID)
Any corrections and insight into why my query can not work, is most welcome.
EDIT: company names can contain digits and/or underscores anywhere, I'm ONLY looking to lock on to a possibly last occurrence of an underscore, followed by an arbitrary natural int. Could be _1, could be _205952 for all I know. There are NO leading zeros in the digits suffix
Upvotes: 5
Views: 368
Reputation: 15251
Something may not be as you believe, since most of the code on this page (including yours) should work, or at least return something.
I would recommend selecting these tables into local temp tables (allowing you to inspect data types/lengths), running ltrim(rtrim(...))
even if you think you don't need to, using N
to mark literals as unicode, explicitly setting the width of your strings, etc. Anything that can increase simplicity or safety could help you find the problem.
Hair-pullers often end as head-slappers.
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))
Also, [SERVER1].[dbo].[TABLE_A]
looks odd for 4-part naming. Do you mean [DB1].[dbo].[TABLE_A]
or [SERVER1].[DB1].[dbo].[TABLE_A]
instead?
Upvotes: 0
Reputation: 1127
Probably this might help:
SELECT * FROM [SERVER1].[dbo].[TABLE_A] a
INNER JOIN [SERVER2].[dbo].[TABLE_B] b
ON a.Name LIKE N'%[_]' + CONVERT(NVARCHAR, b.CompanyID)
I've tested your code and its working perfectly for me. The only reason that could be is that there are no matching records.
Upvotes: 0
Reputation: 1269773
It is possible that your problem is trailing blanks on the company name. The documentation points out:
LIKE supports ASCII pattern matching and Unicode pattern matching. When all arguments (match_expression, pattern, and escape_character, if present) are ASCII character data types, ASCII pattern matching is performed. If any one of the arguments are of Unicode data type, all arguments are converted to Unicode and Unicode pattern matching is performed. When you use Unicode data (nchar or nvarchar data types) with LIKE, trailing blanks are significant; however, for non-Unicode data, trailing blanks are not significant. Unicode LIKE is compatible with the ISO standard. ASCII LIKE is compatible with earlier versions of SQL Server.
This is just a possibility. As a note, when you use varchar
or nvarchar
in a convert()
, you should always include the length. This is not affecting you here.
I think you are better off with this comparison:
cast(SUBSTRING(a.name, charindex('_', a.name)+1, LEN(a.name)) as int) = b.CompanyId
By using an equi-join on CompanyId
, you have the opportunity to use indexes on that column.
Upvotes: 2
Reputation: 487
What you have to do is take that ID out from the name and join on it like here.
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
Upvotes: 2