需要将数据从一列分成多列

时间:2012-05-15 20:15:05

标签: sql sql-server tsql

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

示例:

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

我根本不知道任何字符串的长度。

请帮助我。

由于 SAHA ..

2 个答案:

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

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