将一列拆分为多行

时间:2010-11-22 21:38:48

标签: sql-server

谁能告诉我怎么做到这一点?在某些情况下,我的表中的列包含逗号分隔值。如果是,我需要为这些值创建新行。

此外,作为一个例子,一个表包含1行和4列Col1 | Col2 | Col3 | Col4具有以下值A | B | C |分别为1,2,3。因此,Col4包含字符串'1,2,3',我需要拆分逗号分隔值并将它们放在自己的行上,这样表格就会包含1行,其中1 2和3位于他们自己的行上在Col4。

4 个答案:

答案 0 :(得分:8)

我认为你可以这样做:

SELECT
    T.id, RIGHT(LEFT(T.csv,Number-1),
    CHARINDEX(',',REVERSE(LEFT(','+T.csv,Number-1))))
FROM
    master..spt_values,
    your_table T
WHERE
    Type = 'P' AND Number BETWEEN 1 AND LEN(T.csv)+1
    AND
    (SUBSTRING(T.csv,Number,1) = ',' OR SUBSTRING(T.csv,Number,1)  = '') 

代码在this site无耻地被盗。

答案 1 :(得分:3)

您可以编写一个表格函数,并使用CROSS APPLY将列加入其中。这是我的版本。

CREATE FUNCTION dbo.Splitter(@text nvarchar(max), @separator nvarchar(100))
RETURNS @result TABLE (i int, value nvarchar(max))
AS
BEGIN
    DECLARE @i int
    DECLARE @offset int
    SET @i = 0

    WHILE @text IS NOT NULL
    BEGIN
        SET @i = @i + 1
        SET @offset = charindex(@separator, @text)
        INSERT @result SELECT @i, CASE WHEN @offset > 0 THEN LEFT(@text, @offset - 1) ELSE @text END
        SET @text = CASE WHEN @offset > 0 THEN SUBSTRING(@text, @offset + LEN(@separator), LEN(@text)) END
    END
    RETURN
END

答案 2 :(得分:3)

许多字符串拆分功能中的另一个。这有点类似于@Byron Whitlock的answer,但不是使用master..spt_values使用cte来生成数字表。 SQL Server 2005以后。

CREATE TABLE dbo.Table1 
(
    Col1        CHAR(1),
    Col2        CHAR(1),
    Col3        CHAR(1),
    Col4        VARCHAR(50)
)
GO

INSERT INTO dbo.Table1 VALUES ('A','B','C','1,2,3')
GO

SELECT * FROM dbo.Table1;
GO

WITH
L0 AS(SELECT 1 AS c UNION ALL SELECT 1),
L1 AS(SELECT 1 AS c FROM L0 AS A, L0 AS B),
L2 AS(SELECT 1 AS c FROM L1 AS A, L1 AS B),
L3 AS(SELECT 1 AS c FROM L2 AS A, L2 AS B),
Numbers AS(SELECT ROW_NUMBER() OVER(ORDER BY c) AS n FROM L3)
SELECT  Col1, Col2, Col3,        
        LTRIM(RTRIM(SUBSTRING(valueTable.Col4, nums.n, charindex(N',', valueTable.Col4 + N',', nums.n) - nums.n))) AS [Value]
FROM   Numbers AS nums INNER JOIN dbo.Table1 AS valueTable ON nums.n <= CONVERT(int, LEN(valueTable.Col4)) AND SUBSTRING(N',' + valueTable.Col4, n, 1) = N','

答案 3 :(得分:0)

我知道这是一篇较旧的帖子,但我想我会添加更新。 Tally Table和基于cteTally表的分离器都有一个主要问题。它们使用连接的分隔符,当元素变宽并且字符串变长时会破坏它们的速度。

我已经解决了这个问题,并写了一篇关于它的文章,可以在他的网址中找到。的 http://www.sqlservercentral.com/articles/Tally+Table/72993/

我还会告诉你,一位名叫“彼得”的人甚至对那段代码做了改进(在文章的讨论中)。这篇文章仍然很有趣,我将在接下来的一两天内用Peter的增强功能更新附件。在我的主要增强功能和彼得所做的微调之间,我不相信你会找到一个更快的T-SQL-Only解决方案来分割VARCHAR(8000)。我也解决了VARCHAR(MAX)这类分离器的问题,并且正在为此写一篇文章。