首页 > 解决方案 > SQL Server:用一个现有列的拆分内容更新两列

问题描述

我有一个包含这些列的 SQL Server 表:

ID, Name, FirstName, LastName

所有名称现在都存储在Name列中,我想运行更新以填充FirstName和列。LastName

当前表的示例如下所示:

1 | John Doe | NULL | NULL

在我更新后,我希望这样:

1 | John Doe | John | Doe

为简单起见,可以做出以下假设:

我已经尝试了以下方法(首先作为 SELECT,所以我可以在运行 UPDATE 之前看到输出):

SELECT
    (SELECT TOP 2 value FROM STRING_SPLIT([NAME], ' ')) AS FirstName,   
    (SELECT TOP 1 value FROM STRING_SPLIT([NAME], ' ')) AS LastName 
FROM
    UserTable 
WHERE 
    LastName IS NULL
    AND [NAME] IS NOT NULL

但是,这不起作用,因为第一列将返回前两个顶部条目。但我想获得第二个条目,而不是前两个。第二列(顶部 1)可以正常工作。

我看到它STRING_SPLIT提供了第三个参数-> 序数。这将允许我向子查询添加 WHERE 子句。但是,这仅在 Azure 中可用,但我目前正在运行 SQL Server 2016 (v13)(没有 Azure)。

UPDATE在 SQL Server 2016中实现我的最佳方法是什么?

标签: sql-serversplitsubquery

解决方案


鉴于您指定的特定约束:

您可以使用SUBSTRING和的组合CHARINDEX

  • 注意使用CROSS APPLY (VALUES允许重用CHARINDEX计算
  • 注意使用NULLIF以防止在没有空格的情况下出错
SELECT
  SUBSTRING(t.NAME, 1, v.space - 1) AS FirstName,
  SUBSTRING(t.NAME, v.space + 1, LEN(t.NAME)) AS LastName
FROM UserTable t
CROSS APPLY (VALUES(
    NULLIF(CHARINDEX(' ', t.NAME), 0)
)) v(space)
WHERE t.LastName IS NULL
  AND t.[NAME] IS NOT NULL;

请注意,这绝不是拆分名称的一般解决方案。

名字可以是多种多样的,可能在名字之前有姓氏,可能没有姓氏,可能有多个名字或姓氏等。不要做假设。


推荐阅读