你需要一个 t-sql 字符串“splitter”,但我会不使用上面推荐的 mTVF,因为它非常效率低下并且会破坏并行性。内联表值函数 (iTVF) 是拆分字符串所需的。
我建议使用delimitedSplit8k 或delimitedSplit8k_lead,它们的执行速度会快约30-90 倍;或 STRING_SPLIT 如果您使用的是 SQL 2016+ 并且只需要速度快几百倍的值。请注意此性能测试:
-- sample data
declare @rows int = 10000;
if object_id('tempdb..#strings') is not null drop table #strings;
select top (@rows)
someid = identity(int,1,1),
somestring = replace(right(left(cast(newid() as varchar(36)), 27),21),'-',',')
into #strings
from sys.all_columns a, sys.all_columns b;
-- Performance test
set nocount on;
print 'fn_Analysis_ConvertCsvListToNVarCharTableWithOrder'+char(10)+replicate('-',50);
go
declare @st datetime = getdate(), @item varchar(10);
select @item = [value]
from #strings t
cross apply dbo.fn_Analysis_ConvertCsvListToNVarCharTableWithOrder(t.somestring,',');
print datediff(ms,@st,getdate());
go 5
print 'delimitedSplit8K (serial)'+char(10)+replicate('-',50);
go
declare @st datetime = getdate(), @item varchar(10);
select @item = item
from #strings t
cross apply dbo.DelimitedSplit8K(t.somestring,',')
option (maxdop 1);
print datediff(ms,@st,getdate());
go 5
print 'delimitedSplit8K (parallel)'+char(10)+replicate('-',50);
go
declare @st datetime = getdate(), @item varchar(10);
select @item = item
from #strings t
cross apply dbo.DelimitedSplit8K(t.somestring,',')
option (recompile, querytraceon 8649);
print datediff(ms,@st,getdate());
go 5
结果
fn_Analysis_ConvertCsvListToNVarCharTableWithOrder
--------------------------------------------------
Beginning execution loop
4183
4274
4536
4294
4406
Batch execution completed 5 times.
delimitedSplit8K (serial)
--------------------------------------------------
Beginning execution loop
50
50
50
54
53
Batch execution completed 5 times.
delimitedSplit8K (parallel)
--------------------------------------------------
Beginning execution loop
133
134
133
140
136
Batch execution completed 5 times.
如何解决您的问题
declare @sometable table(someid int identity, someNbr tinyint);
insert @sometable values (1),(3),(6),(12),(7),(15),(19);
declare @searchstring varchar(1000) = '1,2,3,4,19';
select someid, someNbr
from @sometable t
cross apply dbo.DelimitedSplit8K(@searchstring,',') s
where t.someNbr = s.Item;
结果
someid someNbr
----------- -------
1 1
2 3
7 19