sql-server - SQL Server:用一个现有列的拆分内容更新两列
问题描述
我有一个包含这些列的 SQL Server 表:
ID, Name, FirstName, LastName
所有名称现在都存储在Name
列中,我想运行更新以填充FirstName
和列。LastName
当前表的示例如下所示:
1 | John Doe | NULL | NULL
在我更新后,我希望这样:
1 | John Doe | John | Doe
为简单起见,可以做出以下假设:
- 该
Name
列始终包含用空格分隔的名字和姓氏。 - 名字和姓氏总是一个单词的名字,所以没有额外的空格。
我已经尝试了以下方法(首先作为 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中实现我的最佳方法是什么?
解决方案
鉴于您指定的特定约束:
您可以使用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;
请注意,这绝不是拆分名称的一般解决方案。
名字可以是多种多样的,可能在名字之前有姓氏,可能没有姓氏,可能有多个名字或姓氏等。不要做假设。
推荐阅读
- azure-devops - 处理多个项目和一个团队
- java - Java 不能用 replaceAll 方法替换“{”
- csv - 当使用 node-csv-parse 时,你可以指定一些字段是文本限定的,而一些不是?
- javascript - 如何使用css或js选择animation-iteration-count的值?
- android - 在应用程序中打开时在 android?metro 打包程序错误上构建和安装 singed apk
- javascript - jquery 通过 id 选择当前正在播放的音频
- node.js - NodeJs:MongoDB:我想从 ISODate 获取日期,而不需要使用聚合的时间
- sql - 为什么我的查询什么都不返回(SQL 中的营销数据)
- php - Laravel 测试授权路由,中间件身份验证问题
- scala - 在 EPFL 并行编程示例中找不到“并行”结构