2015-05-29 26 views
0

我需要檢索經理的層次結構,並且存儲給定人的經理姓名的列的格式如下Smith, Mr. William (Bill)。我想這個輸出只是William Smith。到目前爲止,我已經把這個一起:如何格式化名/姓的順序並刪除前綴和暱稱

SELECT DISTINCT RIGHT(u.manager, LEN(u.manager)-(1+CHARINDEX(', ', u.manager))) + ' ' + 
LEFT(u.manager, CHARINDEX(', ', u.manager) - 1) as ManagerName 
FROM Users u 

使用我上面的例子查詢目前的結果是Mr. William (Bill) Smith。這個CHARINDEX和SUBSTRING的東西總是給我很多麻煩,所以我不確定最簡單的方法是什麼。這也是一次性的,所以我不確定一個函數在這裏會有用。

回答

2

DEMO

SELECT 
    SUBSTRING(manager,0,CHARINDEX(',', manager)) as surname, 
    SUBSTRING(manager,CHARINDEX('. ', manager)+2, LEN(manager)-CHARINDEX(' (', manager)+1) as name, 
    CONCAT(SUBSTRING(manager,CHARINDEX('. ', manager)+2, LEN(manager)-CHARINDEX(' (', manager)+1), 
     ' ', 
      SUBSTRING(manager,0,CHARINDEX(',', manager))) as 'name surname' 
FROM 
    Users 

結果:

+-------------+-----------+--------------+ 
| surname | name | name surname | 
+-------------+-----------+--------------+ 
    Smith  William William Smith 
0
SELECT RIGHT(NameStripped, LEN(NameStripped) - (1 + CHARINDEX(', ', NameStripped))) + ' ' + LEFT(NameStripped, CHARINDEX(', ', NameStripped) - 1) AS ManagerName --Your original code 
FROM (
    SELECT replace(replace(
      LEFT(u.manager, CHARINDEX('(', u.manager) - 2) --Get rid of nickname 
     , 'Mr. ', ''), 'Ms.', '') AS NameStripped --Get rid of Mr/Ms 
    from MyTable u) a 

這應該工作 - 我使用您發佈的代碼,但添加了一個子查詢來刪除暱稱和前綴。

請注意,如果a)您有更多的前綴選項(比如您可以添加額外的replace s)和/或b)並非數據庫中的每個人都有暱稱(在這種情況下你會想把這部分包裝在case語句中,很可能)。

+0

如果有像Jr.,Sr.,Dr.等前綴那麼這將不起作用。 – FutbolFan

+0

@Nepali - 我同意他需要添加更多的替換,如果數據庫包含其他前綴(請參閱第2段)。由於沒有關於他的數據中有什麼前綴的信息,並且這是一次性操作,所以我寫了最常見的兩個,假設海報可以根據需要添加其他前綴。 – APH

+0

@NepaliRookie我把它寫成「替換」而不是在第一個時期搜索字符串,因爲一些縮寫比前綴更常見的後綴(比如Jr,Sr,PhD),並且因爲有可能數據庫中的某些條目包含標題而沒有他們的一段時間,如小姐。 – APH

1

我把您的查詢,修改一點點:

SELECT 
    ---this is the tricky part: inner part finds the first instance of '(' parenthesis 
    --and substract it from the length of the first name and get only the left part of the first name by subtracting it 
    CONCAT (
     LEFT(t.FirstName, LEN(t.FirstName) - (LEN(t.FirstName) - CHARINDEX('(', t.FirstName) + 1)) 
     ,t.LastName 
     ) 
FROM (
    --basically separating your above syntax to two columns 
    SELECT RIGHT('Smith, Mr. William (Bill)', LEN('Smith, Mr. William (Bill)') - CHARINDEX('.', 'Smith, Mr. William (Bill)') - 1) AS FirstName 
     ,LEFT('Smith, Mr. William (Bill)', CHARINDEX(', ', 'Smith, Mr. William (Bill)') - 1) AS LastName 
    ) t 

這裏是應該與表名和列運行查詢:

SELECT 
    ---Use case when statement to determine if there are any instances of '(' in the first name 
    CONCAT (
    CASE 
     WHEN CHARINDEX('(', t.FirstName) > 0 
      THEN LEFT(t.FirstName, LEN(t.FirstName) - (LEN(t.FirstName) - CHARINDEX('(', t.FirstName) + 1)) 
     ELSE t.FirstName + ' ' 
     END 
    ,t.LastName 
    ) 
FROM (
    SELECT 
    RIGHT(u.manager, LEN(u.manager) - CHARINDEX('.', u.manager) - 1) AS FirstName 
    ,LEFT(u.manager, CHARINDEX(', ', u.manager) - 1) AS LastName from Users u 
) t