【问题标题】:SQL, Split by 1 column and duplicate other columnsSQL,按 1 列拆分并复制其他列
【发布时间】:2015-03-05 15:35:13
【问题描述】:

美好的一天!

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

我试图创建一个 sqlfiddle,但目前页面似乎已关闭。

(SQL Server 2008) 我有一张表,假设它有 3 列,但是设计它的人没有规范化,所以一列包含多个值,是这样的:

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 列包含多个值,所以我需要对两列都这样做)

起初我认为这很容易...但后来我遇到了如何拆分该字符串的问题...首先我考虑使用拆分功能,但后来我不知道如何将其加入与其余列...

提前致谢。

【问题讨论】:

标签: sql-server view split


【解决方案1】:

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

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
;

【讨论】:

  • 太棒了!,交叉应用...从来没有想过,另外,感谢您的拆分功能,比我们这里的要好得多。
猜你喜欢
  • 1970-01-01
  • 2018-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
  • 1970-01-01
  • 2021-07-26
相关资源
最近更新 更多