2017-06-13 33 views
0

私はクエリで別々の部分に分割する必要があるフィールド[名前]を持っています。フィールドは、次の形式になりますSQL Serverの名前フィールドを分割するクエリ

LastName,FirstName PossibleMiddle

サンプル値:出力のための

Doe,John Andrew 
Smith,Jane 

目標:


[LastName]   [FirstName]   [MiddleName] 
---------------- ----------------  ---------------- 
Doe     John     Andrew 
Smith    Jane 

ここでは、私が今までうまくすることができましたコードです。

SELECT 
LEFT([Name], CHARINDEX(',', [Name]) - 1) AS [Last Name], 
SUBSTRING([Name], CHARINDEX(',', [Name]) +1, LEN([Name])) AS [First and Middle Name], 
SUBSTRING([Name], CHARINDEX(',', [Name]) +1, (CHARINDEX(' ', [Name])-1)) AS [First Name] 
FROM t1 

このコードは、理由の説明:
1. 2番目のSUBSTRINGが正しく作成されていないため、失敗します。それは常にスペースがあると仮定しますが、中間の名前があれば実際にはスペースしかありません。
2.私は[ファーストとミドルネーム]を1つにしたくありません(しかし、最初の問題が解決されれば残りは落ちます)。

私はこれで明白な何かを見逃しているように感じますが、まだ試して、解決していない長い朝です。見て反応する時間を取ってくれてありがとうございました。

+3

SQL Serverののバージョンは?新しいものには、ここで使用する可能性のある新しい機能がいくつかあります(たとえば、2016年のSTRING_SPLIT)。そして、あなたはおそらくここで "すべてをキャッチ"することはありません。人の姓が2つの単語の場合はどうなりますか?ファーストネーム?両方が2つの単語の場合はどうなりますか? 1つにはアポストロフィがあればどうなるでしょうか?またはジュニアですか? –

+0

@Jacob H:SQL Serverのバージョンは2008R2です。私はあなたの懸念を感謝し理解する。残念ながら、このクエリは、名前が不適切に設計された方法で格納されているという事実を修正することはありません。最終的には最終的な名前/最初の名前/中間の名前を抽出するだけで、異常があるかどうかを確認して対処することができます。 – RiSt

+0

ただ、SqlZimの答えが2単語の姓の問題を処理していることを指摘したいと思います(データのようなケースが見つかりました)。姓のすべての部分がスペースで区切られている限り、その解決策は機能します。 – RiSt

答えて

0

ので、我々はすべての第二部のための場所で機能を繰り返す必要はありませんcross apply()を使用して:

select 
    lastname = left(t.str,charindex(',',t.str)-1) 
    , firstname = left(x.val,charindex(' ',x.val+' ')) 
    , middlename = nullif(right(x.val,len(x.val)-charindex(' ',x.val)),x.val) 
from t 
    cross apply (
    select val = stuff(t.str,1,charindex(',',t.str),'') 
    ) x(val) 

rextesterデモ:http://rextester.com/TUJNX20615

リターン:

+----------+-----------+------------+ 
| lastname | firstname | middlename | 
+----------+-----------+------------+ 
| Doe  | John  | Andrew  | 
| Smith | Jane  | NULL  | 
+----------+-----------+------------+ 

mononymous個人を含めるように、あなたの例を拡張するには:

create table t (str varchar(32)) 
insert into t values 
('Doe,John Andrew') 
,('Smith,Jane') 
,('Sting') -- mononymous 

select 
    lastname = left(t.str,charindex(',',t.str+',')-1) 
    , firstname = nullif(left(x.val,charindex(' ',x.val+' ')),t.str) 
    , middlename = nullif(right(x.val,len(x.val)-charindex(' ',x.val)),x.val) 
from t 
    cross apply (
    select val = stuff(t.str,1,charindex(',',t.str),'') 
    ) x(val) 

rextesterデモ:http://rextester.com/WPZXC58652

戻ります:

+----------+-----------+------------+ 
| lastname | firstname | middlename | 
+----------+-----------+------------+ 
| Doe  | John  | Andrew  | 
| Smith | Jane  | NULL  | 
| Sting | NULL  | NULL  | 
+----------+-----------+------------+ 
+0

ありがとうございました!これは機能します。乾杯! – RiSt

+0

@RiSt喜んでお手伝いします! – SqlZim

0

私はこれが正しく機能していると思います。基本的には、名前にスペースがあるかどうかに基づいて2つのケースステートメントを使用しました。

名前にスペースが含まれている場合は、最初の名前のスペースを区切ります。そうでなければ、フィールドの残りの部分を取る。

DECLARE @NAME VARCHAR(50) 
SET @NAME = 'Smith,Jane' -- 'Smith,Jane Ann' 

SELECT LEFT(@NAME, CHARINDEX(',', @NAME) - 1) AS LastName, 
    CASE 
     WHEN (CHARINDEX(' ', @NAME) = 0) 
      THEN SUBSTRING(@NAME, CHARINDEX(',', @NAME) + 1, 100) 
     ELSE 
      SUBSTRING(@NAME, CHARINDEX(',', @NAME) + 1, CHARINDEX(' ', @NAME) - CHARINDEX(',', @NAME)) 
    END AS FirstName, 
    CASE 
     WHEN (CHARINDEX(' ', @NAME) = 0) 
      THEN '' 
     ELSE 
      SUBSTRING(@NAME, CHARINDEX(' ', @NAME) + 1, 100) 
    END AS MiddleName 
関連する問題