将字符串中的值提取到多个列中

时间:2012-08-30 21:09:59

标签: sql sql-server sql-server-2008 tsql

我有一个名为Types的表,数据类似于:

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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,你需要额外的逻辑。

答案 2 :(得分:-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