【问题标题】:SPLIT or TRIM Text(String,Varchar) in MSSQL ServerMSSQL Server 中的 SPLIT 或 TRIM Text(String,Varchar)
【发布时间】:2018-04-09 09:51:07
【问题描述】:

我想在表中拆分或“修剪”我的 SQL-Server 中的字段(名称)...但是我在每种尝试的方式中都遇到了错误。

我个人 Better way 声明的示例错误代码:

未找到 SingleWords 列或用户定义的聚合“SingleWords.value”,或者名称不明确。

例如:

我有一个名为:“名称”的字段。此字段包括名字和姓氏(以 CR/LF 或空格分隔)。

对于我的声明,我需要将名称拆分为两个不同的字段..但我只想使用 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 部分,

对于 CR/LF,CHAR(13)+CHAR(10)。

样本数据输入:

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

但我被困在将这 2 个 Select-Statements 组合在一起......

【问题讨论】:

  • 请标记您的 SQL Server 版本。
  • 请提供样本数据和输出
  • 不要为 SQL Server 问题标记 MySQL,它们不是同一个 RDBMS。
  • 另一种说法,你说你有“错误”。请问你能edit你的帖子并包括它们吗?
  • 只看你的样本数据,第一个问题是你有一个人有头衔,然后第二个没有头衔。这立即带来了问题。这是否意味着您还可以具有以下值? Mr SmithMr George W Bush,除非您的数据具有一致性,否则您将无法实现这一目标。如果你不能做出安全的假设,那么你会得到错误的结果。

标签: sql tsql case sql-server-2017


【解决方案1】:

使用您的新数据(您没有标题),可以通过以下方式轻松实现:

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;

然而,正如我在 cmets 中所讨论的,问题是如果您开始使用不只有 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;

【讨论】:

  • 您知道我们如何解决字段中的“标题”问题吗?是否可以使用 if 模式?
  • @XaviLux 在 SQL 服务器中,老实说不要。 Falsehoods Programmers Believe About Names。如果没有非常严格的规则,那么拆分名字的最佳“东西”就是一个人(有太多变量需要以编程方式决定);如果你有这些规则,你可能不会处于现在的位置。:)
  • 在这种情况下,我有一个包含可能标题组合的列表。该字段(catalogEntry)中大约有 20 个标题。那么有可能在 SQL 中创建规则吗?
  • @XaviLux 不,因为在您的原始数据中,您有一个有头衔但没有名字的人;所以我已经知道没有规则。非常严格,我的字面意思是非常严格。如果一个名字可能有名字,也可能没有名字,那已经是太多的变量了。
  • 你说得对,我没有意识到,有时姓氏也可能在字段中丢失...谢谢!
【解决方案2】:

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

// 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

【讨论】:

    【解决方案3】:

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

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

    以下代码现在也有效。此示例会将 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
    

    【讨论】:

      【解决方案4】:

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

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

      我已经用这个解决方案添加了我的SQLFiddle。你可以检查一下。祝你好运!

      【讨论】:

      • 谢谢! @vignesh
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-30
      • 2019-06-08
      • 1970-01-01
      • 2014-05-21
      • 1970-01-01
      • 2011-09-18
      • 2011-08-05
      相关资源
      最近更新 更多