MSSQL Server 中的 SPLIT 或 TRIM Text(String,Varchar)

SPLIT or TRIM Text(String,Varchar) in MSSQL Server

我想拆分或 "trim" 我的 SQL-服务器中的字段(名称) table...但是我尝试过的每一种方法都出错了。

我个人的 Better way 语句的示例错误代码:

The SingleWords column or the user-defined aggregate "SingleWords.value" was not found, or the name is ambiguous.

例如:

我有一个名为:"name" 的字段。此字段包括名字和姓氏(以 CR/LF 或 Space 分隔)。

对于我的声明,我需要将名称拆分为两个不同的字段..但我只想使用 SQL-Management Studio..

这可能吗?

我的 SQL 兼容级别是“130”...

我尝试了以下语句作为示例:

SELECT NAME FROM dbo.CRM_IM_X STRING_SPLIT(Name, CHAR(13)+CHAR(10)) WHERE RTRIM(NAME) <> '';

或(我个人更好的方法):

SELECT CAST('<x>' + REPLACE(NAME,CHAR(13)+CHAR(10),'</x><x>') + '</x>' AS XML) AS SingleWords
    FROM dbo.CRM_IM_X

SELECT SingleWords.value('x[1]','varchar(max)') AS part1
      ,SingleWords.value('x[2]','varchar(max)') AS part2
FROM dbo.CRM_IM_X

名字的第 1 部分,

姓氏的第 2 部分,

CHAR(13)+CHAR(10) 用于 CR/LF.

示例数据输入:

DECLARE @tbl TABLE(NAME VARCHAR(100));
INSERT INTO @tbl VALUES('Jane
Doe'),('John
Doe');

但我无法将这 2 个 Select-语句组合在一起...

以下代码会对您有所帮助,

// You can use the Common Table Expression(CTE).
;WITH Split_Names (SingleWords)
AS
(
   SELECT CONVERT(XML,'<Names><name>'  
                      + REPLACE(Names,' ', '</name><name>') 
                      + '</name></Names>'
                 ) AS SingleWords
   FROM ExampleTable
)

SELECT  SingleWords.value('/Names[1]/name[1]','varchar(100)') AS part1,    
        SingleWords.value('/Names[1]/name[2]','varchar(100)') AS part2,
        SingleWords.value('/Names[1]/name[3]','varchar(100)') AS part3
FROM Split_Names

SQL Fiddle Demo

使用你的新数据(你没有标题),这可以很容易地实现如下:

DECLARE @tbl TABLE(NAME VARCHAR(100));
INSERT INTO @tbl VALUES('Jane
Doe'),('John
Doe');

WITH Replaced AS(
    SELECT REPLACE([NAME],CHAR(13),'') AS [Name]
    FROM @tbl)
SELECT LEFT([name], CHARINDEX(CHAR(10),[Name]) -1) AS FirstName,
       RIGHT([name], LEN([Name]) - (CHARINDEX(CHAR(10),[Name]))) AS Surname
FROM Replaced;

但是,正如我在评论中讨论的那样,问题是如果您开始使用的名称不仅仅包含 2 个部分。作为例子,看看当我们这样做时会发生什么:

DECLARE @tbl TABLE(NAME VARCHAR(100));
INSERT INTO @tbl VALUES('Jane
Doe'),
('John
Doe'),
('Mr
Smith'),
('Mr
Joe
Bloggs'),
('George
W.
Bush'),
('Sir
Friedrich
Harold
Smithe
III');

WITH Replaced AS(
    SELECT REPLACE([NAME],CHAR(13),'') AS [Name]
    FROM @tbl)
SELECT LEFT([name], CHARINDEX(CHAR(10),[Name]) -1) AS FirstName,
       RIGHT([name], LEN([Name]) - (CHARINDEX(CHAR(10),[Name])))
FROM Replaced;

感谢您的帮助! @Larnu 你是对的,如果 CR/LF 也用于标题,你会遇到这个问题,如果我只使用 2 个部分。但是如果我得到第三部分和第四部分,我认为这是可能的,当名称语法每次都是这样的时候:Title(CR/LF),Forename(CR/LF),last name

如果语法不一样,我还需要一个步骤,将名称的正确信息放入我认为正确的字段中?:

以下代码现在也有效。此示例会将 CR/LF 前后的每个单词放在一个新字段中:

DECLARE @tbl TABLE(NAME VARCHAR(100));
INSERT INTO @tbl VALUES('Jane
Doe'),
('John
Doe'),
('Mr
john
Smith'),
('Mr
Joe
Bloggs'),
('George
W.
Bush'),
('Sir
Friedrich
Harold
Smithe
III');

WITH Splitted AS
(
SELECT CAST('<x>' + REPLACE(NAME,CHAR(13)+CHAR(10),'</x><x>') + '</x>' AS XML) AS SingleWords
    FROM @tbl
)
SELECT SingleWords.value('x[1]','varchar(max)') AS part1
      ,SingleWords.value('x[2]','varchar(max)') AS part2
      ,SingleWords.value('x[3]','varchar(max)') AS part3
      ,SingleWords.value('x[4]','varchar(max)') AS part4
FROM Splitted

您可以使用下面给出的简单代码:

SELECT SUBSTRING(Name, 1, CHARINDEX(' ', Name)) AS PART1, 
       SUBSTRING(Name, CHARINDEX(' ', Name), LEN(Name)) AS PART2 
FROM ExampleTable

我已将 SQLFiddle 添加到此解决方案中。你可以检查一下。祝你好运!