SQL,拆分1列并复制其他列

时间:2015-03-05 15:35:13

标签: sql-server view split

美好的一天!

也许你可以帮助我,或者告诉我,我想做的事情是不可能还是完全错误......

我正在尝试创建一个sqlfiddle,但目前该页面似乎已关闭。

SQL Server 2008 )我有一个表,假设它有3列,但设计它的人没有规范化,所以一列保存多个值,它&# 39; s是这样的:

IdCol    Col1    Col2    Col3
  1       a1      b1     a, b, c
  2       a2      b2     d, e, f

如您所见,Col3包含由","

分隔的多个值

我想要实现的目标是创建一个视图(不能修改表格,因为他们不允许我修改应用程序),这类似于:

NewIdCol     IdCol    Col1     Col2     Col3
1            1        a1       b1       a
2            1        a1       b1       b
3            1        a1       b1       c
4            2        a2       b2       d
5            2        a2       b2       e
6            2        a2       b2       f

因此,最终结果将Col3值拆分为不同的行,并复制每个其他列的值。 (实际表有大约20列,其中2列包含多个值,因此我需要为两列执行此操作)

起初我认为这很容易......但是我在如何分割字符串方面遇到了障碍......首先我想到了使用拆分函数,但后来我还不知道如何加入它与其余的列一起回来......

提前致谢。

1 个答案:

答案 0 :(得分:2)

您需要具有将逗号分隔的字符串拆分为单独行的函数。然后你调用这个函数:

SELECT
    NewIdCol = ROW_NUMBER() OVER(ORDER BY t.IdCol, x.ItemNumber),
    t.IdCol,
    t.Col1,
    t.Col2,
    x.Item
FROM Test t
CROSS APPLY [dbo].[DelimitedSplit8K](t.Col3, ',') x 

以下是Jeff Moden的DelimitedSplit8K函数。


CREATE FUNCTION [dbo].[DelimitedSplit8K](
    @pString NVARCHAR(4000), @pDelimiter NCHAR(1)
)
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
WITH E1(N) AS (
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
)
,E2(N) AS (SELECT 1 FROM E1 a, E1 b)
,E4(N) AS (SELECT 1 FROM E2 a, E2 b)
,cteTally(N) AS(
    SELECT TOP (ISNULL(DATALENGTH(@pString),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
,cteStart(N1) AS(
    SELECT 1 UNION ALL 
    SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString,t.N,1) = @pDelimiter
),
cteLen(N1,L1) AS(
SELECT 
    s.N1,
    ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,8000)
FROM cteStart s
)
SELECT 
    ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1),
    Item       = SUBSTRING(@pString, l.N1, l.L1)
FROM cteLen l
;