从列

时间:2018-10-30 11:40:49

标签: c# sql-server vb.net ssis

我正在尝试清除SQL服务器数据库中的一列文本(如果重要的话,请在Azure中)。

文本中包含民族名称,并带有大量的后缀(博士,教授,医学博士,博士学位,MSC和许多我不希望使用的可疑字符,;,;, (, )等< / p>

我想从这些行中删除很多东西-通常在一个字段中多次删除-我以为最好的方法是将它们添加到表中,并使用它来遍历并替换每个每个空格都有一个空格,在最后修剪并用一个空格替换多个空格之前,因为即使只将我需要删除的所有术语的1/3移出嵌套嵌套的替换公式,也看起来很疯狂。

最后-我想要的输出是将名字分为第一名,中间名和姓氏。一切都很干净,没有其他信息。

到目前为止,我一直在SSIS中处理数据,并探索了标准的T-SQL转换(使用嵌套的replace(),但增长得如此之快以至于令人讨厌)。我已经研究了派生列-再次看来,嵌套替换是这里唯一可行的选择!我终于尝试使用脚本组件找到解决方案,但是作为一名业余爱好者,我一直无法弄清楚如何使用它,也没有找到任何示例。

效率也是一个问题,因为我最初需要处理大约80万个名称。

由于我已经寻找了很长时间,但是没有发现任何直接帮助的东西,我将非常感谢。

2 个答案:

答案 0 :(得分:2)

兔子漏洞,挑战全名存储在一个字段中,然后在T-SQL中解析它,并保留所有免责声明。

清理数据,尤其是text / varchar / nvarchar列是一项挑战,无论上面提到的那些项目如何,因为您发现嵌套的REPLACE可能会失控并且难以管理。

您可以在t-sql中做几件事,以帮助您完成所要完成的工作。所有这些将需要对数据进行多次传递。我看到这分为两个清洁类别。 1-删除定义的单词,2-特殊字符。

  • 将您的案例名称前缀和后缀中的“单词”放入要删除的表中。
  • 基本上去除所有非字母字符。

如果我的名字前缀或后缀是“ Dean”或“ Miss”或...,名字是“ Dean Smith”或“ Missy”或...,是的,那是兔子洞。暂且不说,这里是一些示例代码,您可以尝试一下。

--Test table for words I want to strip out.
DECLARE @WordsToRemove TABLE
    (
        [word] NVARCHAR(200)
    );

--Test table for my data I want to clean
DECLARE @TestData TABLE
    (
        [Data] NVARCHAR(500)
      , [CleanData] NVARCHAR(500)
    );

--Flag I am using to keep my while loops going
DECLARE @Continue INT;


--Insert of the words I want to remove.
INSERT INTO @WordsToRemove (
                         [word]
                     )
VALUES ( 'DR' )
     , ( 'D.R.' )
     , ( 'M.D.' )
     , ( 'md' )
     , ( 'Prof.' );

--Insert test names to clean.  I have a while loop here, was loading my test table with 10000+ recrods to see performance.
--You can leave the while loop here commented out just to see how the code works.  I got under 2 minutes for 100000+ records.  Your mileage may vary.
--WHILE (SELECT COUNT(*) FROM   @TestData) < 100000
    --BEGIN
        INSERT INTO @TestData (
                              [Data]
                          )
        VALUES ( N'DR Jimmy Smith' )
             , ( 'D.R. John Jones M.D.' )
             , ( 'Timothy Neal DR md' )
             , ( 'Prof. Bob Smith Dr M.D.' )
             , ( 'Taco;,,; Johns Dr. Prof.' )
             , ( 'Prof. ''#%^Special Charaters;,,; Dr. Prof.' );
    --END;

--Just updating a another column so I can save original state
UPDATE @TestData
SET    [CleanData] = [Data]


--Join to my @WordsToRemove table using PATINDEX, continue doing that until all occurrences have been removed.
--Clean out words we dont want
SET @Continue = 1;
WHILE @Continue = 1
    BEGIN
        SET @Continue = 0;
        UPDATE     [a]
        SET        [a].[CleanData] = REPLACE([a].[CleanData], [b].[word], '')
                 , @Continue = 1
        FROM       @TestData [a]
        INNER JOIN @WordsToRemove [b]
            ON PATINDEX('%' + [b].[word] + '%', [a].[CleanData]) > 0;
    END;

--Remove all non-alpha characters, preserving spaces
--PATINDEX using "%[^a-z ]%" looks of anything not a character and not a space.
SET @Continue = 1;
WHILE @Continue = 1
    BEGIN
        SET @Continue = 0;
        UPDATE [a]
        SET    [a].[CleanData] = STUFF([a].[CleanData], PATINDEX('%[^a-z ]%', [a].[CleanData]), 1, '')
             , @Continue = 1
        FROM   @TestData [a]
        WHERE  PATINDEX('%[^a-z ]%', [a].[CleanData]) > 0;
    END;

SELECT *
FROM   @TestData;

然后从那里,根据数据存储的格式,提取所需的每个部分。

答案 1 :(得分:1)

这仅解决了部分问题,但是,我想详细说明这一点。我不希望在这里投票,但是不会发表评论。

首先“最后-我想要的输出是将名称分为第一名,中间名,姓氏。所有内容都很干净,没有其他信息。” 不会发生。名称有太多变化。读过Falsehoods Programmers Believe About Names,看似愚蠢,但这是真的。

例如,您假设(错误地),是将名称分为几部分,并用空格分隔。第一部分标题,第二个名字,姓氏是姓氏,中间的任何东西都是中间名。请看以下示例:

Mr John Smith
Mrs Jane Alice Wallis Smith
Mr Dick van Dyke
Sarah Brown

很明显,首先,对于第一人称,“ John”是他的名字,“ Smith”是他的姓氏,还有“头衔”先生。那第二个呢?瓦利斯是中间名吗?如果可能是双桶姓(您怎么知道?)最后一个人呢? “ van Dyke”是全名。然后,您有最后一个条目,标题甚至丢失了;那里发生了什么?

就像我说的那样,您不能使用SQL拆分名称。您必须具有一些非常聪明的机器学习工具。