SQL 语句从提供的字符串开头截断字段?

标签 sql sql-server

我有一个很大的 SQL 表;一个字段包含用户的姓名,后面通常是我需要删除的各种内容才能获得他们的“普通”姓名(不要问!)例如:

<pre>Mark Johnson
Joe Bloggs (DO NOT USE)
Mick Bronson (refer Jim Bloggs)
Jan Morrison
Jemima Thomson refer Joe harrison
Glen Grabs-Moffat try harry

后缀大约有 20 种类型。我想创建一个 UPDATE 查询(我猜可能是 20),它将从我提供的字符串的开头“修剪”值,例如“(DO”或“(ref”)以仅获取“Joe Bloggs”,而没有postfix。最好不区分大小写。

有什么想法吗?

谢谢

编辑:

我使用的代码如下所示:

for (int count = 0; count < ExpenseItems.Count; count++)
            {
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf("(DO NOT").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf("(DON'T").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf("(DONT ").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf("(DONOT").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" DO NOT").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" DON'T").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" DONT ").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" DONOT").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf("(pls").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf("(please").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" pls").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" please").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf("(refer").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" refer").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" (Re").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" (ref to").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" ref to").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" (refto").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" refto").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" use ").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" try ").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf("(see ").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" see ").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf("director").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" never ").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.TruncateFromStartOf(" moved").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.Replace("DISABLED", "(D)").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.Replace("disabled", "(D)").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.Replace("Disabled", "(D)").Trim();
                ExpenseItems[count].Requester_Name = ExpenseItems[count].Requester_Name.Replace("DISALBED", "(D)").Trim();
            }

截断的效果正如 jar 头上所说的那样:

    public static string TruncateFromStartOf(this string input, string splitString, bool caseSensitive = false, int offset = 0)
    {
        //Verify input
        if (string.IsNullOrEmpty(input))
            return string.Empty;

        if (string.IsNullOrEmpty(splitString))
            return input;

        int segmentIndex = -1;
        //the start of the segment in the input string
        if (caseSensitive)
        {
            segmentIndex = input.IndexOf(splitString, StringComparison.Ordinal);
        }
        else
        {
            segmentIndex = input.ToLower().IndexOf(splitString.ToLower(), StringComparison.Ordinal);
        }

        if (segmentIndex == -1)
            return input; //nothing to remove

        //Return the parts around the segment
        return input.Substring(0, segmentIndex + offset);
    }

最佳答案

将排除词放入表格中,而不是存储在代码中:

CREATE TABLE dbo.TruncationWords
(
       Word VARCHAR(32) NOT NULL UNIQUE
);

INSERT dbo.TruncationWords(Word) 
SELECT '(DO NOT'
UNION ALL SELECT '(DON''T'
UNION ALL SELECT '(DONT'
UNION ALL SELECT '(DONOT'
UNION ALL SELECT 'DO NOT'
UNION ALL SELECT 'DON''T'
UNION ALL SELECT 'DONT'
UNION ALL SELECT 'DONOT'
UNION ALL SELECT '(pls'
UNION ALL SELECT '(please'
UNION ALL SELECT 'pls'
UNION ALL SELECT 'please'
UNION ALL SELECT '(refer'
UNION ALL SELECT 'refer'
UNION ALL SELECT '(Re'
UNION ALL SELECT '(ref to'
UNION ALL SELECT 'ref to'
UNION ALL SELECT '(refto'
UNION ALL SELECT 'refto'
UNION ALL SELECT 'use'
UNION ALL SELECT 'try'
UNION ALL SELECT '(see'
UNION ALL SELECT 'see'
UNION ALL SELECT 'director'
UNION ALL SELECT 'never'
UNION ALL SELECT 'moved'
UNION ALL SELECT 'disabled';

现在您可以轻松地将这些单词与任何表/列交叉引用。例如:

DECLARE @t TABLE (Name VARCHAR(255));

INSERT @t SELECT 'Mark Johnson'
UNION ALL SELECT 'Joe Bloggs (DO NOT USE)'
UNION ALL SELECT 'Mick Bronson (refer Jim Bloggs)'
UNION ALL SELECT 'Jan Morrison'
UNION ALL SELECT 'Jemima Thomson refer Joe harrison'
UNION ALL SELECT 'Glen Grabs-Moffat try harry'
UNION ALL SELECT 'Can''t touch this';

;WITH x AS
(
  SELECT 
    t.Name, 
    Trunc = LEFT(t.Name, CHARINDEX(' ' + w.Word, t.Name)),
    rn = ROW_NUMBER() OVER (PARTITION BY t.Name ORDER BY CHARINDEX(' ' + w.Word, t.Name))
   FROM @t AS t
   INNER JOIN dbo.TruncationWords AS w
   ON CHARINDEX(' ' + w.Word, t.Name) > 0
)
UPDATE src
  SET src.Name = x.Trunc
  FROM @t AS src
  INNER JOIN x 
  ON src.Name = x.Name
  WHERE x.rn = 1;

SELECT Name FROM @t;

结果:

Name
--------------------------
Mark Johnson
Joe Bloggs
Mick Bronson
Jan Morrison
Jemima Thomson
Glen Grabs-Moffat
Can't touch this

该解决方案做出两个假设:

  1. 您要截断的单词始终以空格分隔。
  2. 排序规则不区分大小写。您可以使用 COLLATE条款来解决这个问题。

而且我认为像'see'这样的词是有问题的。如果某人的名字是“John Seek”,该怎么办?

关于SQL 语句从提供的字符串开头截断字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10711886/

相关文章:

mysql - 我可以像这样从 select 调用 mysql SP 吗?

sql - 在 SET 赋值中,您可以使用变量以编程方式定义应为 SET 的列名吗?

sql - 使用 UDF 拆分值对和创建表

sql - 如何创建 SELECT 查询 FROM "TABLE1 AND TABLE2"

sql - 如果以相同的顺序访问对象,如何会发生死锁?

mysql - 从另一个表中选择计数仅显示其存在的 1 行

MySQL 使用 Group By 选择最大出现次数

sql - 使用 SqlAlchemy 进行内部连接

sql-server - 无法从选择查询的结果中复制包含 JSON 数据的大列

c# - 从存储过程中返回错误代码值是好的做法吗?