2017-04-19 34 views
0

我发现下面的代码片段在线:查找字符串最长的单词与SQL

DECLARE @str VARCHAR(5000)= 'aaaa bbbbb cccccccc ddddddddddddddddddd' 

SELECT TOP 1 Split.a.value('.', 'VARCHAR(100)') as longest_Word 
FROM (SELECT Cast ('<M>' + Replace(@str, ' ', '</M><M>') + '</M>' AS XML) AS Data) AS A 
     CROSS APPLY Data.nodes ('/M') AS Split(a) 
ORDER BY Len(Split.a.value('.', 'VARCHAR(100)')) DESC 

其中发现在一个文本文件中最长的单词(“ddddddddddddddddddd在这种情况下)。但是,我不知道如何在某一列中应用此行,以便在每行的旁边添加一列,告诉我在SQL Server中最长的单词是什么。

在SQL Server中的每一列在其中需要搜索应该是这样的旁边添加到它的额外的列:

COLUMN 1  RESULT 
ABC ABCD  ABCD 
BC BCDE  BCDE 
9II IIIIV IIIIV 
...   ... 
+2

你对领带做什么? – SqlZim

+0

@SqlZim好点。我会留意OP的回应。 –

+0

@JohnCappelletti我只是好奇。已经提高了您的答案,因为无论答案如何,这都将是一个小调整。 – SqlZim

回答

2

简单CROSS APPLY可以帮助在这里。

请注意,我用我自己的XML解析器,因为它是 “XML安全”

Declare @YourTable table ([COLUMN 1] varchar(max)) 
Insert Into @YourTable values 
('ABC ABCD'), 
('BC BCDE'), 
('9II IIIIV') 

Select A.[COLUMN 1] 
     ,Result = B.RetVal 
From @YourTable A 
Cross Apply (
       Select Top 1 * 
       From (
         Select RetSeq = Row_Number() over (Order By (Select null)) 
           ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) 
         From (Select x = Cast('<x>' + replace((Select replace(A.[COLUMN 1],' ','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
         Cross Apply x.nodes('x') AS B(i) 
         ) B1 
       Order by Len(RetVal) Desc,RetSeq 
      ) B 

返回

COLUMN 1 Result 
ABC ABCD ABCD 
BC BCDE BCDE 
9II IIIIV IIIIV 

编辑 - 要显示纽带

Declare @YourTable table ([COLUMN 1] varchar(max)) 
Insert Into @YourTable values 
('ABC ABCD'), 
('BC BCDE 1234'), 
('9II IIIIV') 

Select A.[COLUMN 1] 
     ,Result = B.RetVal 
From @YourTable A 
Cross Apply (
       Select Top 1 with ties * 
       From (
         Select RetSeq = Row_Number() over (Order By (Select null)) 
           ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) 
         From (Select x = Cast('<x>' + replace((Select replace(A.[COLUMN 1],' ','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
         Cross Apply x.nodes('x') AS B(i) 
         ) B1 
       Order by Dense_Rank() over (Order by Len(RetVal) Desc) 
      ) B 

退货

COLUMN 1  Result 
ABC ABCD  ABCD 
BC BCDE 1234 BCDE --<< Tie 
BC BCDE 1234 1234 --<< Tie Added for Illustration 
9II IIIIV  IIIIV 
+0

这看起来不错。一个小小的评论是,如果这些字段包含标点符号(如逗号,句号和括号),则该代码将有效地将它们视为它们相邻的任何单词的一部分。为了避免这种情况,在应用上面的逻辑之前,可以用空格替换每个有问题的标点符号。尽管对于某些角色来说,这可能会很尴尬 - 比如单词内部和周围都可能存在的撇号。 –

+0

@SteveLovell真的,但OP没有提及任何标点符号。如果是这种情况,还有其他技术可以“正常化”字符串。目前,我将把它作为空间划分的面值 –

+0

感谢John的帮助,但是这仍然是基于你自己的输入检验。实际上我想将其应用于现有列的现有表。但用我的表名替换@yourtable不适用于列名。 – Probs

相关问题