2017-10-11 29 views
2

我想潑data列到3分新列SQL字符串由逗號溢出和空間

  1. 最後
  2. 第一

數據有空格或值 ''逗號分開。

data 
ABC, RICK SEAN, MD 
MES, AEL B, MD FACC 
DAN, RK, MD 
OHI, NIK, MD F 
KA E SYME, PA-C 
ALL MUD, SIM, MD 
RINE EEMAN, FNP-C 
ABC, PQR DIR 

所需的輸出:

desc      last  first  post 

ABC, RICK SEAN, MD   ABC   RICK SEAN MD   
MES, AEL B, MD FACC   MES   AEL B  MD FACC 
DAN, RK, MD     DAN   RK   MD 
OHI, NIK, MD F    OHI   NIK   MD F 
KA E SYME, PA-C    KA   E SYME  PA-C 
ALL MUD, SIM, MD   ALL MUD  SIM   MD 
RINE EEMAN, FNP-C   RINE  EEMAN  FNP-C 
ABC, PQR DIR    ABC   PQR   DIR 

檢查第一行數據列有2個逗號和最後一排只有一個逗號。

樣品這裏http://rextester.com/BEHUP42399

select left(data, charindex(',', data) -1) from TTT 

它嘗試了「最後」的名字列,但給人錯誤o對於「KAè賽姆」即一個逗號記錄/ P創建。 如果數據有單個逗號,並且在逗號之前只有一個單詞表示逗號後有兩個單詞,那麼結果就是。檢查最後一個記錄ABVC。

eg. ABC, PQR DIR     
+0

別人怎麼能知道,電子賽姆和全是泥不應該分開?這背後的原因是什麼? –

+0

這個答案可能對你有幫助:https://stackoverflow.com/a/46595896/2225030 –

+0

你最好在應用程序代碼中完成它。 SQL不適合這份工作 – GurV

回答

2

你可以嘗試使用它CROSS APLLY

SELECT N.DATA [descr], 
     CASE 
      WHEN N.last = '' 
      THEN LTRIM(N.first) 
      ELSE LTRIM(N.last) 
     END last, 
     CASE 
      WHEN N.last = '' 
      THEN SUBSTRING(LTRIM(N.post), 1, CHARINDEX(CHAR(32), LTRIM(N.post))) 
      ELSE LTRIM(N.first) 
     END first, 
     CASE 
      WHEN N.last = '' 
      THEN SUBSTRING(LTRIM(N.post), (CHARINDEX(' ', LTRIM(N.post))+1), LEN(LTRIM(N.post))) 
      ELSE LTRIM(N.post) 
     END post 
FROM 
(
    SELECT D.DATA, 
      CASE 
       WHEN D.post IS NULL 
       THEN LEFT(D.last, CHARINDEX(' ', D.last)) 
       ELSE D.last 
      END last, 
      CASE 
       WHEN d.post IS NULL 
       THEN SUBSTRING(D.last, (CHARINDEX(' ', D.last)+1), LEN(D.last)) 
       ELSE d.first 
      END first, 
      CASE 
       WHEN D.post IS NULL 
       THEN d.first 
       ELSE d.post 
      END post 
    FROM 
    (
     SELECT DISTINCT 
       DATA, 
       Split.a.value('/M[1]', 'NVARCHAR(MAX)') last, 
       Split.a.value('/M[2]', 'NVARCHAR(MAX)') first, 
       Split.a.value('/M[3]', 'NVARCHAR(MAX)') post 
     FROM 
     (
      SELECT DATA, 
        CAST('<M>'+REPLACE(DATA, ',', '</M><M>')+'</M>' AS XML) AS String 
      FROM #TM 
     ) A 
     CROSS APPLY String.nodes('/M') Split(a) 
    ) D 
) N; 

所需的結果:

desc      last  first  post 

ABC, RICK SEAN, MD   ABC   RICK SEAN MD   
MES, AEL B, MD FACC   MES   AEL B  MD FACC 
DAN, RK, MD     DAN   RK   MD 
OHI, NIK, MD F    OHI   NIK   MD F 
KA E SYME, PA-C    KA   E SYME  PA-C 
ALL MUD, SIM, MD   ALL MUD  SIM   MD 
RINE EEMAN, FNP-C   RINE  EEMAN  FNP-C 
ABC, PQR DIR    ABC   PQR   DIR 

注:以上結果按提供的數據。

+0

它的工作用於2個逗號分隔的字符串。什麼是單逗號字符串。像RINE EEMAN,FNP-C –

+0

ITs工作,但我還有一個條件。 Sampel數據中添加了新條件。 –

+0

@rohitpatil檢查已更新。 –

1

你可以嘗試像下面

邏輯查詢的是,我們發現逗號的數量,並添加逗號的第一次出現空格時逗號小於3 這時候有沒有逗號的所有字符串也適用。

create table staging_tbl_single_row (data varchar(max)) 
insert into staging_tbl_single_row values 
('ABC, RICK SEAN, MD') 
,('MES, AEL B, MD FACC') 
,('DAN, RK, MD') 
,('OHI, NIK, MD F') 
,('KA E SYME, PA-C') 
,('ALL MUD, SIM, MD') 
,('RINE EEMAN, FNP-C'), 
('ABC, PQR DIR'); 

; with cte as 
(
select 
    row_number() over (order by (select NULL)) as column1, 
    column2= 
    case 
     when 
      (len(data)-len(replace(data,',',''))=2) 
     then 
      data 
     when 
      (len(data)-len(replace(data,',',''))=1) 
     then 
      case --check if space is to the left of comma 
        when 
         charindex(' ',left(data, charindex(',',data)))<>0 
        then 
         stuff(data,charindex(' ',data),1,',') 
        else 
         left(data, charindex(',',data))+ 
         stuff(
          substring(data, 
             charindex(',',data)+1, 
             len(data) 
            ), 
          charindex(' ', 
             substring(
              data, 
              charindex(',',data)+1, 
              len(data) 
             ), 
             2) 
          ,1,',') 
        end 

     when 
      (len(data)-len(replace(data,',',''))=0) 
     then 
       stuff(
     stuff(data,charindex(' ',data),1,',') 
     ,charindex(' ',stuff(data,charindex(' ',data),1,',')) 
     ,1,',') 

    end,data 
    from 
    staging_tbl_single_row 
) 

select 
    last=[1],first=[2],post=[3] 
from 
(
    select 
     t.column1, 
     split_values=SUBSTRING(t.column2, t1.N, ISNULL(NULLIF(CHARINDEX(',',t.column2,t1.N),0)-t1.N,8000)), 
     r= row_number() over(partition by column1 order by t1.N) 
    from cte t 
     join 
     (
      select 
       t.column2, 
       1 as N 
      from cte t 
       UNION ALL 
      select 
       t.column2, 
       t1.N + 1 as N 
      from cte t 
       join 
       (
       select 
        top 8000 
         row_number() over(order by (select NULL)) as N 
       from 
        sys.objects s1 
         cross join 
        sys.objects s2 
       ) t1 
      on SUBSTRING(t.column2,t1.N,1) = ',' 
     ) t1 
      on t1.column2=t.column2 
)a 
pivot 
( 
    max(split_values) for r in ([1],[2],[3]) 
    )p 

see working demo

+0

你可以檢查這個條件ABC,PQR DIR嗎? sry我忘記提及 –

+0

它的工作,但對於100萬條記錄需要很長時間。 +1 –

0
;WITH Split_Names (data, xmlname) 
AS 
(
    SELECT data, 

    CONVERT(XML,'<Names><name>' 
    + REPLACE(data,',', '</name><name>') + '</name></Names>') AS xmlname 
     FROM TTT 
) 

SELECT CASE 
      WHEN s.post IS NULL 
      THEN LEFT(s.last, CHARINDEX(' ', s.last)-1) 
      ELSE s.last 
     END last, 
     CASE 
      WHEN s.post IS NULL 
      THEN SUBSTRING(s.last, (CHARINDEX(' ', s.last)+1), LEN(s.last)) 
      ELSE s.first 
     END first, 
     CASE 
      WHEN s.post IS NULL 
      THEN s.first 
      ELSE s.post 
     END Post FROM 
(
SELECT data,  
xmlname.value('/Names[1]/name[1]','varchar(MAX)') AS Last,  
xmlname.value('/Names[1]/name[2]','varchar(MAX)') AS First, 
xmlname.value('/Names[1]/name[3]','varchar(MAX)') AS Post 
FROM Split_Names 
)s 
+0

你能檢查這個條件ABC,PQR DIR嗎?我忘記提到了 –

相關問題