Sql server 将逗号分隔的字段拆分为大量行
我试图将数据从一个模式迁移到另一个模式,但在拆分逗号分隔的字段时遇到了一些问题 S1:源数据库 S2:目标数据库 S1有一个名为ownerUserIDList的字段,该字段链接到S2中的AMID,问题是S2在此字段中只允许1个值,而S1可以有多个值,并且在数据库中以逗号分隔,因此我的计划是拆分字段,并使用拆分的最后一个元素更新S2 问题是它花费的时间太长,而且经常超时。该表大约有60万行。我已经尝试了一些我发现的方法,但是对于一个大的数据集来说,没有一种方法看起来真的那么快 下面的所有示例都将成为实际数据迁移的update语句,这些只是为了比较运行计时 方法1:Sql server 将逗号分隔的字段拆分为大量行,sql-server,tsql,Sql Server,Tsql,我试图将数据从一个模式迁移到另一个模式,但在拆分逗号分隔的字段时遇到了一些问题 S1:源数据库 S2:目标数据库 S1有一个名为ownerUserIDList的字段,该字段链接到S2中的AMID,问题是S2在此字段中只允许1个值,而S1可以有多个值,并且在数据库中以逗号分隔,因此我的计划是拆分字段,并使用拆分的最后一个元素更新S2 问题是它花费的时间太长,而且经常超时。该表大约有60万行。我已经尝试了一些我发现的方法,但是对于一个大的数据集来说,没有一种方法看起来真的那么快 下面的所有示例都将成
SELECT TOP 100000 CASE
WHEN ownerUserIDList LIKE '%,%' THEN SUBSTRING( ownerUserIDList , LEN(ownerUserIDList) - CHARINDEX(',',REVERSE(ownerUserIDList)) + 2 , LEN(ownerUserIDList) )
ELSE ownerUserIDList
END
FROM S1.UserTable WHERE ownerUserIDList != '' AND ownerUserIDList IS NOT NULL
SELECT TOP 100000 value
FROM S1.UserTable
CROSS APPLY STRING_SPLIT(ownerUserIDList, ',')
WHERE ownerUserIDList != '' AND ownerUserIDList IS NOT NULL
GO
SQL Server执行时间:CPU时间=2359毫秒,运行时间=
728479毫秒
方法2:
SELECT TOP 100000 CASE
WHEN ownerUserIDList LIKE '%,%' THEN SUBSTRING( ownerUserIDList , LEN(ownerUserIDList) - CHARINDEX(',',REVERSE(ownerUserIDList)) + 2 , LEN(ownerUserIDList) )
ELSE ownerUserIDList
END
FROM S1.UserTable WHERE ownerUserIDList != '' AND ownerUserIDList IS NOT NULL
SELECT TOP 100000 value
FROM S1.UserTable
CROSS APPLY STRING_SPLIT(ownerUserIDList, ',')
WHERE ownerUserIDList != '' AND ownerUserIDList IS NOT NULL
GO
SQL Server执行时间:CPU时间=1719毫秒,运行时间=
399817毫秒
考虑到我必须在多个甚至更大的表上运行类似的查询,这两种方法都非常慢。有没有其他方法可以更快地拆分这些字段
表格结构非常简单:
S1:
UserID ownerUserIDList S2_AMID
---------------------------------------
1 20 1
2 20, 21, 23 4
3 21, 22, 23 4
AMID S1_UserID
-----------------
1 20
2 21
3 22
4 23
S2:
UserID ownerUserIDList S2_AMID
---------------------------------------
1 20 1
2 20, 21, 23 4
3 21, 22, 23 4
AMID S1_UserID
-----------------
1 20
2 21
3 22
4 23
如果你真的只想要最后一个条目,试试这个。可以添加子句以避免空列表或单条目列表
declare @t table(UserID int, OwnerID varchar(50))
insert @t values (1,'1,2,3'),(2,'3,4,5'),(3,'6,7,8')
select *, left(reverse(ownerID),CHARINDEX(',',reverse(ownerID))-1) from @t
这是非常接近你的第一个选择,但我怀疑你会更接近。可能是CLI功能?我会让其他人来编写代码。如果你真的只想要最后一个条目,试试这个。可以添加子句以避免空列表或单条目列表
declare @t table(UserID int, OwnerID varchar(50))
insert @t values (1,'1,2,3'),(2,'3,4,5'),(3,'6,7,8')
select *, left(reverse(ownerID),CHARINDEX(',',reverse(ownerID))-1) from @t
这是非常接近你的第一个选择,但我怀疑你会更接近。可能是CLI功能?我将让其他人来编写代码。SQL Server不擅长处理字符串,如果您的主要目标是获得拆分字符串的最佳性能,您可以尝试使用
CLR
函数
您可以获得有关
CLR
函数的更多详细信息SQL Server不擅长处理字符串,如果您的主要目标是获得拆分字符串的最佳性能,您可以尝试CLR
函数
您可以获得有关
CLR
函数的更多详细信息在我没有时间学习CLR函数之前,我从未使用过这些函数,但感谢这一点,这将有助于今后的工作。在我没有时间学习这些函数之前,我从未使用过CLR函数,但感谢这一点,这将有助于今后的工作。这一点很有效,在稍微修改一下更新查询之后,创建链接花费了6秒钟。谢谢这很有效,在稍微修改一下更新查询后,创建链接需要6秒钟。谢谢