我正在尝试清除SQL服务器数据库中的一列文本(如果重要的话,请在Azure中)。
文本中包含民族名称,并带有大量的后缀(博士,教授,医学博士,博士学位,MSC和许多我不希望使用的可疑字符,;,;,
(, )
等< / p>
我想从这些行中删除很多东西-通常在一个字段中多次删除-我以为最好的方法是将它们添加到表中,并使用它来遍历并替换每个每个空格都有一个空格,在最后修剪并用一个空格替换多个空格之前,因为即使只将我需要删除的所有术语的1/3移出嵌套嵌套的替换公式,也看起来很疯狂。
最后-我想要的输出是将名字分为第一名,中间名和姓氏。一切都很干净,没有其他信息。
到目前为止,我一直在SSIS中处理数据,并探索了标准的T-SQL转换(使用嵌套的replace(),但增长得如此之快以至于令人讨厌)。我已经研究了派生列-再次看来,嵌套替换是这里唯一可行的选择!我终于尝试使用脚本组件找到解决方案,但是作为一名业余爱好者,我一直无法弄清楚如何使用它,也没有找到任何示例。
效率也是一个问题,因为我最初需要处理大约80万个名称。
由于我已经寻找了很长时间,但是没有发现任何直接帮助的东西,我将非常感谢。
答案 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拆分名称。您必须具有一些非常聪明的机器学习工具。