将逗号分隔的字段拆分为大量行

时间:2019-01-29 02:33:50

标签: sql-server tsql

我正在尝试将数据从一种模式迁移到另一种模式,并且在拆分以逗号分隔的字段时遇到一些问题。

S1:源数据库

S2:目标数据库

S1有一个名为 ownerUserIDList 的字段,该字段链接到S2中的 AMID ,问题是S2在此字段中只允许1个值,而S1可以有多个且是逗号在数据库中定界,所以我的计划是拆分字段,并使用拆分的最后一个元素更新S2。

问题是它花费的时间太长,并且不断地超时。该表大约有60万行。我尝试了一些在SO上发现的方法,但是对于大型数据集,似乎没有一个方法真的那么快。

下面的所有示例都将变为用于实际数据迁移的更新语句,这些只是用于比较运行时间。

方法1:

public class ExitActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_exit);

        android.os.Process.killProcess(android.os.Process.myPid());
    }
}
  

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
  

SQL Server执行时间:CPU时间= 1719毫秒,经过的时间=   399817毫秒。

考虑到我将不得不在多个甚至更大的表上运行类似的查询,因此这两种方法都非常慢。还有其他方法可以更快地拆分这些字段吗?

表结构非常简单:

S1

SELECT TOP 100000 value 
FROM S1.UserTable
    CROSS APPLY STRING_SPLIT(ownerUserIDList, ',') 
    WHERE ownerUserIDList != '' AND ownerUserIDList IS NOT NULL
GO

S2

UserID    ownerUserIDList   S2_AMID
---------------------------------------
1           20              1
2           20, 21, 23      4
3           21, 22, 23      4

2 个答案:

答案 0 :(得分:2)

如果您真的只想要最后一个条目,请尝试此操作。您可以添加子句以避免空或单条目列表。

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功能?我将它留给其他人来进行编码。

答案 1 :(得分:2)

SQL Server不擅长处理字符串,如果您的主要目标是获得最佳的拆分字符串性能,则可以尝试使用CLR函数。

您可以获取有关CLR函数here

的更多详细信息