2012-05-15 40 views
-1

我在编写将数据从一列分隔为多列的查询时遇到问题。需要将数据从一列分隔为多列

例子:

Col1 
--------------------------- 
bank.wrong.transaction 
bank.wrong.transaction.captured 
business.unit.explored.wrong.way 
application.failed 

需要把数据放到列如下:

col1  col2   col3 
-------------------------------------------------  
wrong  transaction null 
wrong  transaction captured 
unit  explored  wrong 
failed null   null 

我不知道任何字符串的长度都没有。

请帮我这个。

感谢 萨哈..

+0

可能重复的[删除和分割的数据到选择语句的多个列(http://stackoverflow.com/questions/1735791/remove-and-split-data-into-多列选择语句) –

+0

为什么要扔掉数据的'a.'部分? *全部*数据是否有领先的'a.'?如果不是,你可以显示一些其他的例子,你想如何看待输出? –

+2

当然最好是重新设计并摆脱这一点,你不应该以这种方式对数据进行处理。 – HLGEM

回答

1

类似于下面的东西可以用来让你请求的输出(我来自哪里抢了ParseString功能着回忆 - 我却用它所有的时间,伟大工程)

CREATE FUNCTION dbo.fnParseString 
    (
     @Section SMALLINT , 
     @Delimiter CHAR , 
     @Text VARCHAR(MAX) 
    ) 
RETURNS VARCHAR(8000) 
AS 
    BEGIN 
     DECLARE @NextPos SMALLINT , 
      @LastPos SMALLINT , 
      @Found SMALLINT 

     --#### Uncomment the following 2 lines to emulate PARSENAME functionality 
     --IF @Section > 0 
     -- SELECT @Text = REVERSE(@Text) 

     SELECT @NextPos = CHARINDEX(@Delimiter, @Text, 1) , 
       @LastPos = 0 , 
       @Found = 1 

     WHILE @NextPos > 0 
      AND ABS(@Section) <> @Found 
      SELECT @LastPos = @NextPos , 
        @NextPos = CHARINDEX(@Delimiter, @Text, @NextPos + 1) , 
        @Found = @Found + 1 

     RETURN CASE 
      WHEN @Found <> ABS(@Section) OR @Section = 0 THEN NULL 
      --#### Uncomment the following lines to emulate PARSENAME functionality 
      --WHEN @Section > 0 THEN REVERSE(SUBSTRING(@Text, @LastPos + 1, CASE WHEN @NextPos = 0 THEN DATALENGTH(@Text) - @LastPos ELSE @NextPos - @LastPos - 1 END)) 
      WHEN @Section > 0 THEN SUBSTRING(@Text, @LastPos + 1, CASE WHEN @NextPos = 0 THEN DATALENGTH(@Text) - @LastPos ELSE @NextPos - @LastPos - 1 END) 

      ELSE SUBSTRING(@Text, @LastPos + 1, CASE WHEN @NextPos = 0 THEN DATALENGTH(@Text) - @LastPos ELSE @NextPos - @LastPos - 1 END) 
     END 
    END 



DECLARE @TestData VARCHAR(255) 
SET @TestData = 'business.unit.explored.wrong.way' 

SELECT dbo.fnParseString(2, '.', @TestData) , 
     dbo.fnParseString(3, '.', @TestData) , 
     dbo.fnParseString(4, '.', @TestData) , 
     dbo.fnParseString(5, '.', @TestData) , 
     dbo.fnParseString(6, '.', @TestData) 
+0

非常感谢@HeavenCore .. – Shahsra

+0

真棒代码..真的很感激它.. – Shahsra

0

那么你还没有回答任何问题,但我会展示如何在没有冗长函数的情况下以这种方式提取数据,如果我的一些假设是正确的(例如,你只关心中间三个值):

DECLARE @x TABLE(col1 VARCHAR(255)); 

INSERT @x 
SELECT 'bank.wrong.transaction' 
UNION ALL SELECT 'bank.wrong.transaction.captured' 
UNION ALL SELECT 'business.unit.explored.wrong.way' 
UNION ALL SELECT 'application.failed'; 

WITH x(col1, d) AS 
( 
    SELECT col1, SUBSTRING(col1, CHARINDEX('.', col1) + 1, 255) + 
    CASE WHEN LEN(col1) - LEN(REPLACE(col1, '.', '')) BETWEEN 1 AND 3 THEN 
    REPLICATE('./', 4-(LEN(col1)-LEN(REPLACE(col1, '.', '')))) ELSE '' END 
    FROM @x 
) 
SELECT orig = col1, 
    col1 = NULLIF(PARSENAME(d, 4), '/'), 
    col2 = NULLIF(PARSENAME(d, 3), '/'), 
    col3 = NULLIF(PARSENAME(d, 2), '/') 
FROM x; 

结果:

orig        col1  col2   col3 
-------------------------------- ---------- ----------- -------- 
bank.wrong.transaction   wrong  transaction NULL 
bank.wrong.transaction.captured wrong  transaction captured 
business.unit.explored.wrong.way unit  explored  wrong 
application.failed    failed  NULL   NULL