2017-04-19 60 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

相關問題