2014-10-22 23 views
0

我正在尋找解決方案以獲取從另一個字符串中提取的基於字符的字符串。 我只需要來自另一個字符串的前4個「字符」。 這裏的限制是「另一個」字符串可能包含空格,特殊字符,數字等,可能少於4個字符。從sql server中的另一個字符串獲取字符唯一的字符串

例如 - 我應該得到

  1. 「NAGP」 如果源字符串爲 「那格浦爾區」

  2. 「ILLF」 如果源字符串是 「惡運」

  3. 「 RAJU「如果源字符串是」RA123 * JU23「

  4. 如果源字符串是」MAC「,則爲」MAC「

任何幫助,非常感謝。

感謝您分享您的時間和智慧。

+0

你有沒有試圖以任何方式解決這個問題呢? – Tanner 2014-10-22 11:07:38

+0

只需使用像這樣的解決方案來刪除非字母字符:http://stackoverflow.com/questions/1007697/how-to-strip-all-non-alphabetic-characters-from-string-in-sql-server,然後取前4個字符。 – Tanner 2014-10-22 11:10:26

回答

1

您可以使用問題的答案,並添加子串的方法來獲得你想要的長度值 How to strip all non-alphabetic characters from string in SQL Server?

Create Function [dbo].[RemoveNonAlphaCharacters](@Temp VarChar(1000)) 
Returns VarChar(1000) 
AS 
Begin 

    Declare @KeepValues as varchar(50) 
    Set @KeepValues = '%[^a-z]%' 
    While PatIndex(@KeepValues, @Temp) > 0 
     Set @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '') 

    Return @Temp 
End 

使用它像

Select SUBSTRING(dbo.RemoveNonAlphaCharacters('abc1234def5678ghi90jkl'), 1, 4); 

這裏SUBSTRING用於從返回的值中獲取長度爲4的字符串。

+0

謝謝Satyajit。您的解決方案工作。感謝您的大力幫助。 – IrfanRaza 2014-10-22 11:29:31

1
^([a-zA-Z])[^a-zA-Z\n]*([a-zA-Z])?[^a-zA-Z\n]*([a-zA-Z])?[^a-zA-Z\n]*([a-zA-Z])? 

您可以試試這個。抓取抓圖或抓圖。參見demo。

http://regex101.com/r/rQ6mK9/42

+0

你如何使用T-SQL? ;) – 2014-10-22 11:13:02

+0

@LucasTrzesniewski組在T-SQL中不可用? :( – vks 2014-10-22 11:13:37

+0

AFAIK你需要定義一個CLR函數來獲得任何在T-SQL中的正則表達式支持(並且我不把* LIKE *模式稱爲正則表達式)... – 2014-10-22 11:25:11

0

有點晚了這裏的聚會,但作爲一般規則,我鄙視所有功能與BEGIN .. END,他們幾乎從來沒有每當我看到一個表現良好,而且由於這涵蓋了所有的標量函數(直到微軟實現inline scalar expressions),因爲這樣的我尋找一種提供類似可重用性的替代方案。在這種情況下,查詢可以被轉換爲內嵌表值函數:

CREATE FUNCTION dbo.RemoveNonAlphaCharactersTVF (@String NVARCHAR(1000), @Length INT) 
RETURNS TABLE 
AS 
RETURN 
( WITH E1 (N) AS 
    ( SELECT 1 
     FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) n (N) 
    ), 
    E2 (N) AS (SELECT 1 FROM E1 CROSS JOIN E1 AS E2), 
    N (Number) AS (SELECT TOP (LEN(@String)) ROW_NUMBER() OVER(ORDER BY E1.N) FROM E2 CROSS JOIN E1) 
    SELECT Result = ( SELECT TOP (ISNULL(@Length, 1000)) SUBSTRING(@String, n.Number, 1) 
         FROM N 
         WHERE SUBSTRING(@String, n.Number, 1) LIKE '[a-Z]' 
         ORDER BY Number 
         FOR XML PATH('') 
        ) 
); 

所有這樣做是使用數字的列表,以擴大出串入列,例如RA123 *JU23T變爲:

Letter 
------ 
R 
A 
1 
2 
3 

* 
J 
U 
2 
3 
T 

不在數字字母然後被where子句除去行:

WHERE SUBSTRING(@String, n.Number, 1) LIKE '[a-Z]' 

離開

Letter 
------ 
R 
A 
J 
U 
T 

然後@Length參數限制的字符(在您的情況這將是4),然後使用XML連接重建字符串。我通常會使用FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')進行xml連接以允許使用xml字符,但由於我知道沒有我沒有打擾,因爲它是額外的開銷。

運行一些測試在此用的1,000,000行一個示例表:

CREATE TABLE dbo.T (String NVARCHAR(1000)); 
INSERT T (String) 
SELECT TOP 1000000 t.String 
FROM (VALUES ('Nagpur District'), ('Ill Fated'), ('RA123 *JU23'), ('MAC')) t (String) 
     CROSS JOIN sys.all_objects a 
     CROSS JOIN sys.all_objects B 
ORDER BY a.object_id; 

然後比較所述標量和內聯的UDF(稱爲如下):

SELECT COUNT(SUBSTRING(dbo.RemoveNonAlphaCharacters(t.String), 1, 4)) 
FROM T; 

SELECT COUNT(tvf.Result) 
FROM T 
     CROSS APPLY dbo.RemoveNonAlphaCharactersTVF (t.String, 4) AS tvf; 

超過15的測試運行(可能對於一個準確的數字還不夠,但足以描繪圖片)標量UDF的平均執行時間爲11.824s,而內聯TVF的平均執行時間爲1.658,因此速度大約快85%。

相關問題