2010-03-17 21 views
2

我有一個文本列VARCHAR(4000)與文本:SQL服務器:更換文本字段相同的字符序列(TSQL僅)

'aaabbaaacbaaaccc'

,我需要刪除所有重複的字符 - 因此,只有一個來自序列左側:

'abacbac' 

它不應該是一個函數,Procedure或者CLR - Regex解決方案。只有真正的SQL選擇。

目前我想用遞歸WITH子句替換'aa' - >'a','bb' - >'b','cc' - >'c'。

所以遞歸應該循環,直到所有字符的重複序列都被替換。

您是否有另一種解決方案,或許性能更好?

PS:我通過這個網站搜索了不同的替換例子 - 它們不適合這種情況。

+0

這聽起來像一個家庭作業問題。爲什麼沒有功能? – CResults 2010-03-17 23:03:31

+1

是的,一種測試。但我想檢查一下遞歸「WITH」變體是否可以。 沒有功能,因爲我知道如何實現這個功能。 找到最佳的SQL本機方法非常有用。 – zmische 2010-03-17 23:29:01

+0

我可以添加助手錶嗎?這將是非常小,但有,哦,我不知道,4000行:) – CResults 2010-03-17 23:30:19

回答

3

假設

CREATE TABLE myTable(rowID INT IDENTITY(1,1), dupedchars NVARCHAR(4000)) 

和數據表的定義..

INSERT INTO myTable 
     SELECT 'aaabbaaacbaaaccc' 
     UNION 
     SELECT 'abcdeeeeeffgghhaaabbbjdduuueueu999whwhwwwwwww' 

此查詢符合您的標準

WITH Numbers(n) 
     AS 
     ( SELECT 1 AS n 
      UNION ALL 
      SELECT (n + 1) AS n 
       FROM Numbers 
      WHERE n < 4000 
     ) 
    SELECT rowid, 
     ( SELECT CASE 
      WHEN SUBSTRING(dupedchars,n2.n,1) = SUBSTRING(dupedchars+' ',n2.n+1,1) THEN '' 
      ELSE SUBSTRING(dupedchars,n2.n,1) 
      END AS [text()] 
      FROM myTable t2,numbers n2 
      WHERE n2.n <= LEN(dupedchars) 
      AND t.rowid = t2.rowid 
      FOR XML path('') 
     ) AS deduped 
    FROM myTable t 
    OPTION(MAXRECURSION 4000) 

輸出

rowid deduped 
    1 abacbac 
    2 abcdefghabjdueueu9whwhw 
+0

CResults:這是神奇的! ))我以爲幾乎差不多。但不同的方法。你的一個更普遍! 謝謝! 那麼100000行的表的性能問題呢? 我是否正確,它是唯一一個通過Native SQL完成此任務的選項? – zmische 2010-03-18 06:41:21

+0

對於很多行,您正在查看大約10秒的執行時間。替代品(我最初看到的)將是一個具有索引的Numbers的物理表。你*可能會從中得到一些改進,但查詢的慢速部分是重複 - 這種類型的任何字符串操作都會帶來速度開銷。 – CResults 2010-03-18 09:31:05

+0

注意10秒鐘是基於類似於上面的字符串長度。如所暗示的那樣,這個時間涉及到重複數據刪除。將所有字段設置爲4000個字符,並且每分鐘查看大約1000個結果。如果您的字段中存在重複值,則只會通過向此查詢提供唯一值來獲得優化。 – CResults 2010-03-18 09:43:11