簡體   English   中英

在 SQL 中使用交叉應用時查找兩個表之間的匹配值

[英]Find matching values between two tables when using cross apply in SQL

我正在嘗試從表 A 列 x中提取 5 個或更多連續數字,並將提取的數字與表 B 列 z匹配。 如果該值存在,那很好,但如果該值不存在,則需要將其插入到Table B中。 我已經設法從表 A中提取了數字,但是在嘗試JOIN時我被卡住了,因為我正在使用CROSS APPLYCASE 也許我只是不明白如何做到這一點。

我用來提取數字的代碼:

SELECT nvt.AdditionalInformation,
       CASE
           WHEN M.FirstMatch > 0
           THEN SUBSTRING(AdditionalInformation, M.FirstMatch-1, N.SecondMatch-1)
          
           --check IF TPNumber EXISTS in ChangeRequests table then add ChangeRequest Id to ReportVersionChangeRequests table
           ELSE NULL
       END
FROM
(
    SELECT ':'+nvt.AdditionalInformation+':' AdditionalInformation
    FROM dbo.NSReportVtest nvt
) nvt

CROSS APPLY(VALUES(PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', ':'+nvt.AdditionalInformation+':'))) M(FirstMatch)
CROSS APPLY(VALUES(PATINDEX('%[^0-9]%', SUBSTRING(AdditionalInformation, M.FirstMatch-1, LEN(AdditionalInformation))))) N(SecondMatch)

目前這是代碼的結果:

表 A:

附加信息 (無列名)
:試驗結果: NULL
:試驗結果: 256985
:試驗結果: NULL
:試驗結果: NULL
:試驗結果: NULL
:試驗結果: 85965

預期成績:

表 A:

附加信息 (無列名)
:試驗結果: NULL
:試驗結果: 256985
:試驗結果: NULL
:試驗結果: NULL
:試驗結果: NULL
:試驗結果: 85965

表 B:

ID 數字
1 61758
2 85965
3 56456
4 78945

Join后預期的 Output

表 C:

ID 數字
1 61758
2 85965
6 56456
8 78945
9 256985(添加條目)
create table NSReportVtest (AdditionalInformation nvarchar(max)) -- Source table
create table NSReportVtest2 (id int identity(1,1) ,Value int) -- destination table


insert into NSReportVtest  --- creating source data 
select 'aaa256985bbb'
union all select 'aasa123456babb'
union all select 'aaga245bfbb'
union all select 'abaa54123bnbb'
union all select 'aaba654987bmbb'
union all select 'aacabybb'


insert into NSReportVtest2(Value) -- creating dest data 
select 123456
union all select 54123 


insert into NSReportVtest2  --- inserting missing data using left join 
select cast( substring(SUBSTRING(AdditionalInformation,PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', AdditionalInformation), LEN(AdditionalInformation)) ,1,PATINDEX('%[^0-9]%',SUBSTRING(AdditionalInformation,PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', AdditionalInformation), LEN(AdditionalInformation))) -1 ) as int) Value
 from  NSReportVtest t1
left outer join  NSReportVtest2 t2
on cast( substring(SUBSTRING(AdditionalInformation,PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', AdditionalInformation), LEN(AdditionalInformation)) ,1,PATINDEX('%[^0-9]%',SUBSTRING(AdditionalInformation,PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', AdditionalInformation), LEN(AdditionalInformation))) -1 ) as int) = t2.Value
where t2.id is null 
and  cast( substring(SUBSTRING(AdditionalInformation,PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', AdditionalInformation), LEN(AdditionalInformation)) ,1,PATINDEX('%[^0-9]%',SUBSTRING(AdditionalInformation,PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', AdditionalInformation), LEN(AdditionalInformation))) -1 ) as int)  <>0 

我找到了一個可行的解決方案。 INSERT INTO到一個#temp表中,然后我可以 select 特定列並將其連接到第二個表,這樣可以更輕松地管理數據。

SELECT nv.AdditionalInformation, 
       nv.Id,
       CASE
           WHEN M.FirstMatch > 0
           THEN SUBSTRING(AdditionalInformation, M.FirstMatch-1, N.SecondMatch-1)
           ELSE NULL
       END AS ExtractedTP
INTO #temp
FROM
(
    SELECT ':'+nv.AdditionalInformation+':' AdditionalInformation, 
           nv.Id
    FROM dbo.NSReportVtest nv
) nv
CROSS APPLY(VALUES(PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', ':'+nv.AdditionalInformation+':'))) M(FirstMatch)
CROSS APPLY(VALUES(PATINDEX('%[^0-9]%', SUBSTRING(AdditionalInformation, M.FirstMatch-1, LEN(AdditionalInformation))))) N(SecondMatch);

--select and join temp table to ChangeRequests table to see which TP Numbers exist

SELECT t.Id, 
       t.ExtractedTP, 
       nrt.TPNumber, 
       nrt.Id
FROM #temp t
     LEFT JOIN dbo.NSChangeRequestsTest nrt ON t.ExtractedTP = nrt.TPNumber
ORDER BY t.ExtractedTP DESC;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM