我有两个用Id填充的临时表。
#Master表来自一个系统,而#Extended表来自另一个系统,其中人们已将字符添加到Id。
我现在遇到的问题是编写SELECT
查询以检查是否存在匹配,或者是否一次删除一个字符,直到匹配为止。正如您在下面看到的那样,在这种情况下将不存在完全匹配的情况我只想返回一个可能的值(1-12L7QABC可以返回1-12L7QO或1-12L7QM)。
CREATE TABLE #Master(Id nvarchar(15), ClientName nvarchar(35));
INSERT INTO #Master
VALUES('1-12L7QO', 'John Citizen'),
('1-12L7QM', 'Steve Smith'),
('1-10YL', 'Sarah Connor'),
('1-2CN9WN', 'Cathy Rodgers');
CREATE TABLE #Extended(ExtId varchar(15));
INSERT INTO #Extended
VALUES('1-12L7QO`'),
('1-12L7QABC'),
('1-10YL'),
('1-12L7QMTest');
预期输出为:
+---------------+---------------+-----------------------------------+
| Id | BaseId | Name |
+---------------+---------------+-----------------------------------+
| 1-12L7QO` | 1-12L7QO | John Citizen |
| 1-12L7QABC | 1-12L7QO | John Citizen |
| 1-10YL | 1-10YL | Sarah Connor |
| 1-12L7QMTest | 1-12L7QM | Steve Smith |
+---------------+---------------+-----------------------------------+
答案 0 :(得分:1)
一种方法是创建所有可能的子串,然后进行匹配:
with m as (
select m.id, m.ClientName
from #Master m
union all
select left(m.id, len(m.Id) - 1), m.ClientName
from m
where m.Id <> ''
)
select e.ExtId, m.Id, m.ClientName
from #Extended e outer apply
(select top 1 m.*
from m
where e.ExtId like m.id + '%'
order by len(m.id) desc
) m;
我不想说这是有效的,但它应该做你想要的。并且,它在一个小数据集上很好。
答案 1 :(得分:1)
试一试:完全按照自己的意愿工作。
CREATE TABLE #MasterMatch(RowId INT,Master_Id nvarchar(15), ExtId varchar(15),ClientName nvarchar(35),Rank_Got Decimal(20,4));
Select row_number() over(order by ExtId desc) as RowId,ExtId into #Extended1 from #Extended
Declare @Id_Len INT
Declare @Rec_Cnt INT
Declare @ExtId varchar(15)
Declare @ExtId1 varchar(15)
SET @Rec_Cnt = (SELECT Count(1) FROM #Extended1)
Print @Rec_Cnt
WHILE(@Rec_Cnt > 0)
BEGIN
SELECT @ExtId = ExtId from #Extended1 where Rowid = @Rec_Cnt
SET @ExtId1 = @ExtId
SELECT @Id_Len = Len(@ExtId)
WHILE (@Id_Len > 2)
BEGIN
IF EXISTS (SELECT 1 FROM #Master WHERE Id = @ExtId)
BEGIN
INSERT INTO #MasterMatch
SELECT @Rec_Cnt,Id As Master_Id,@ExtId1 AS ExtId,ClientName,(CONVERT(DECIMAL(20,4),@Id_Len)/CONVERT(DECIMAL(20,4),@Rec_Cnt)) As Rank_Got FROM #Master WHERE Id = @ExtId
SET @Id_Len = (@Id_Len - 1)
SET @ExtId = SUBSTRING(@ExtId,0,@Id_Len)
END
ELSE
BEGIN
INSERT INTO #MasterMatch
SELECT @Rec_Cnt,Id As Master_Id,@ExtId1 AS ExtId,ClientName,(CONVERT(DECIMAL(20,4),@Id_Len)/CONVERT(DECIMAL(20,4),@Rec_Cnt)) As Rank_Got FROM #Master WHERE Id like @ExtId + '%'
SET @Id_Len = (@Id_Len - 1)
SET @ExtId = SUBSTRING(@ExtId,0,@Id_Len)
END
END
SET @Rec_Cnt = (@Rec_Cnt - 1)
END
Select Id,Base_id,Name
FROM (
Select ROW_NUMBER() OVER(Partition by ExtId ORDER BY Master_Id) As SnId,ExtId As Id,Master_Id As Base_id,ClientName As Name FROM #MasterMatch a INNER JOIN (select RowId,MAX(Rank_Got) As Rank_Got from #MasterMatch GROUP BY RowId) b on a.RowId = b.RowId and a.Rank_Got = b.Rank_Got
) one
WHERE one.SnId = 1