2012-08-30 34 views
0

我有一個表稱爲類型和數據是這樣的:提取值的爲多列

Item_Name 

Hardware \ Hardware Laptop \ Display 
Application \ Application Configuration Request 
Application \ Application File Request 
Application 

我試圖將它們分成3個不同的列。因此,試圖通過下面的查詢做:

select parsename(replace([Item_Name],'\','.'),3) as First, 
parsename(replace([Item_Name],'\','.'),2) as Second, 
parsename(replace([Item_Name],'\','.'),1) as third 
from dbo.Types 

,但我沒有得到確切的結果,我想輸出是:

First   Second          Third 
Hardware  Hardware Laptop        Display 
Application Application Configuration Request   NULL 
Application Application File Request     NULL 
Application NULL          NULL 

但我得到的輸出爲:

First   Second       Third 
Hardware  Hardware Laptop     Display 
NULL   Application      Application Configuration Request   
NULL   Application      Application File Request      
NULL   NULL       Application 
+1

什麼'parsename'? – egrunin

+1

@egrunin:http://msdn.microsoft.com/en-us/library/ms188006.aspx – Blorgbeard

+0

我喜歡聰明的事情,但我不喜歡以這種方式使用PARSENAME。 – GilM

回答

2

這可能是有用的

Declare @t table(Item_Name Varchar(100)) 
Insert Into @t 
Select 'Hardware \ Hardware Laptop \ Display' Union All 
Select 'Application \ Application Configuration Request' Union All 
Select 'Application \ Application File Request' Union All 
Select 'Application' 

;WITH CTE AS(
SELECT 
    Item_Name 
    ,NoOfOccurance = (LEN(Item_Name) - LEN(REPLACE(Item_Name, '\', ''))) 
    ,New_Item_Name = CASE (LEN(Item_Name) - LEN(REPLACE(Item_Name, '\', ''))) 
         WHEN 0 THEN 'Col1 \ Col2 \ ' +Item_Name 
         WHEN 1 THEN 'Col1 \ ' +Item_Name 
         ELSE Item_Name 
        END 
FROM @t) 
,cte2 AS(
SELECT 
    [First] = LEFT(New_Item_Name,CHARINDEX('\',New_Item_Name,0)-1) 
    , [Second] = SUBSTRING(
       New_Item_Name 
       ,CHARINDEX('\',New_Item_Name,0)+1 
       ,CHARINDEX('\',SUBSTRING(New_Item_Name,CHARINDEX('\',New_Item_Name,0)+1,len(New_Item_Name)),0)-1 
       ) 
    ,[Third] = REVERSE(LEFT(REVERSE (New_Item_Name),CHARINDEX('\',REVERSE (New_Item_Name),0)-1)) 

FROM CTE) 
SELECT 
    [First] = CASE WHEN LTRIM(RTRIM([First])) = 'Col1' THEN REPLACE([First], 'Col1', NULL) ELSE [First] END 
    ,[Second] = CASE WHEN LTRIM(RTRIM([Second])) = 'Col2' THEN REPLACE([Second], 'Col2', NULL) ELSE [Second] END 
    ,[Third]  
FROM Cte2 

//結果

First Second Third 
Hardware  Hardware Laptop  Display 
NULL  Application  Application Configuration Request 
NULL  Application  Application File Request 
NULL NULL  Application 
0

我認爲這個蠻力,但它的作品。這個想法是在最後添加足夠的斜槓來創建一個全名。這會推翻一切:

with types as (select 'Hardware \ Hardware Laptop \ Display' as item_name union all 
       select 'Application \ Application Configuration Request' union all 
       select 'Application \ Application File Request' union all 
       select 'Application' 
      ) 
select parsename(replace([Item_Name]+suffix, '\', '.'), 3) as First, 
     parsename(replace([Item_Name]+suffix, '\', '.'), 2) as Second, 
     parsename(replace([Item_Name]+suffix, '\', '.'), 1) as third 
from (select item_name, LEN(Item_name) - LEN(replace(item_name, '\', '')) as numslash, 
      REPLICATE('. ', 2-(LEN(Item_name) - LEN(replace(item_name, '\', '')))) as suffix 
     from Types 
    ) t 

一個細微的區別是,它會爲空插槽生成空格而不是NULL。如果你想要NULL,你需要額外的邏輯。

+0

「額外的邏輯」可能是NULLIF('parsename ...,3)','')'作爲第一個... – GilM

-1
WITH CTE AS(
SELECT CASE LEN(Item_Name)-LEN(REPLACE(Item_Name,'\','')) WHEN 2 THEN [Item_Name] WHEN 1 THEN 
     [Item_Name]+'.' Else [Item_Name]+'..' as Item_Name 
FROM dbo.Types 
) 
SELECT parsename(Item_Name,'\','.'),3) as First, 
     parsename(Item_Name,'\','.'),2) as Second, 
     parsename(Item_Name,'\','.'),1) as third 
FROM CTE 
+0

很多錯誤(缺少一些REPLACE(s),不起作用,價值(像上一節中的空間)... – GilM