如何将逗号分隔的值放入带有多个逗号分隔值的行中

时间:2019-09-25 07:15:30

标签: sql sql-server

我有一个像这样的字符串:

a,b,c(a,b,c),d,e,L(e,d,g)

我希望它像这样:

1. a
2. b
3. c(a,b,c)
4. d
5. e
6. L(e,d,g)

在MSSQL查询中。

4 个答案:

答案 0 :(得分:0)

那么您可以使用UNION或创建表并在其中插入此类数据。

联盟示例


@Injectable({
   providedIn: 'root'
})

以此类推。

@EDIT:

了解一下,根据评论,您可以在这里偷看答案: https://stackoverflow.com/a/5493616/8416043

我不会在这里重复它。

祝你好运

答案 1 :(得分:0)

IF OBJECT_ID('tempdb..#Data')IS NOT NULL
DROP TABLE #Data

CREATE TABLE #Data
(
    ID INT IDENTITY(1,1),
    String VARCHAR(MAX)
)


INSERT #Data SELECT 'a,b,c(a,b,c),d,e,L(e,d,g)'

UPDATE T SET String=REPLACE(REPLACE(String,'(','('''),')',''')') FROM #Data T

IF OBJECT_ID('tempdb..#T')IS NOT NULL
DROP TABLE #T

DECLARE @FieldSeparator VARCHAR(10)='(',@FieldSeparator1 VARCHAR(10)=')'

;WITH CTE AS
(
    SELECT
        ID,
        LEFT(String, CHARINDEX(@FieldSeparator, String + @FieldSeparator) - 1) DataItem,
        STUFF(String, 1, CHARINDEX(@FieldSeparator, String + @FieldSeparator), '') String
    FROM #Data
    UNION all
    SELECT
        ID,
        LEFT(String, CHARINDEX(@FieldSeparator, String + @FieldSeparator) - 1),
        STUFF(String, 1, CHARINDEX(@FieldSeparator, String + @FieldSeparator), '')
    FROM CTE
    WHERE String > ''
)
SELECT
    ID,
    DataItem AS String
INTO #T
FROM CTE WHERE CHARINDEX(@FieldSeparator1,DataItem)>0
ORDER BY ID


--SELECT * FROM #T

IF OBJECT_ID('tempdb..#T1')IS NOT NULL
DROP TABLE #T1

;WITH CTE AS
(
    SELECT
        ID,
        LEFT(String, CHARINDEX(@FieldSeparator1, String + @FieldSeparator1) - 1) DataItem,
        STUFF(String, 1, CHARINDEX(@FieldSeparator1, String + @FieldSeparator1), '') String
    FROM #T
    UNION ALL
    SELECT
        ID,
        LEFT(String, CHARINDEX(@FieldSeparator1, String + @FieldSeparator1) - 1),
        STUFF(String, 1, CHARINDEX(@FieldSeparator1, String + @FieldSeparator1), '')
    FROM CTE
    WHERE String > ''
)
SELECT
    ID,
    DataItem,
                DataItem NewString 
INTO #T1
FROM CTE WHERE CHARINDEX('''',DataItem)>0
ORDER BY ID

--SELECT * FROM #T1

UPDATE #T1 SET NewString=REPLACE(REPLACE(NewString,',','|'),'''','')

UPDATE #T1 SET DataItem='('+DataItem+')',NewString='('+NewString+')'

ALTER TABLE #T1 ADD Rn INT

UPDATE A SET A.Rn=Rn1 FROM
(
SELECT *,ROW_NUMBER()OVER(ORDER BY ID ASC)Rn1 FROM #T1 
)A


DECLARE @Start INT =1,@End INT=(SELECT MAX(Rn) FROM #T1),@Str VARCHAR(1000),@Id INT


WHILE @Start<=@End
BEGIN 

                UPDATE T SET T.String=REPLACE(T.String,T1.DataItem,T1.NewString) FROM #Data T
                INNER JOIN #T1 T1 ON T.ID=T1.Id AND T1.Rn=@Start

                SET @Start=@Start+1

END


--SELECT * FROM #Data
DECLARE @FieldSeparator2 VARCHAR(10)=','

;WITH CTE AS
(
    SELECT
        ID,
        LEFT(String, CHARINDEX(@FieldSeparator2, String + @FieldSeparator2) - 1) DataItem,
        STUFF(String, 1, CHARINDEX(@FieldSeparator2, String + @FieldSeparator2), '') String
    FROM #Data
    UNION all
    SELECT
        ID,
        LEFT(String, CHARINDEX(@FieldSeparator2, String + @FieldSeparator2) - 1),
        STUFF(String, 1, CHARINDEX(@FieldSeparator2, String + @FieldSeparator2), '')
    FROM CTE
    WHERE String > ''
)
SELECT
    ID,
    REPLACE(REPLACE(DataItem,'|',','),'''','') AS String
FROM CTE 
ORDER BY ID

答案 2 :(得分:0)

通过足够的创造性工作,一切皆有可能,但是SQL Server确实不是进行复杂文本操作的地方:

declare @start varchar(max) = 'a,b,c(a,b,c),d,e,L(e,d,g)'

declare @inter1 varchar(max) = REPLACE(REPLACE(@start,'(','<b><a>'),')','</a></b>')

declare @inter2 varchar(max) = '<c><a>' + REPLACE(@inter1,',','</a><a>') + '</a></c>'

select REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(CONVERT(varchar(max),x.query('.')),'</a><a>',','),'<b><a>','('),'</a></b>',')'),'</a>',''),'<a>','')
from (select CONVERT(xml,@inter2)) t (abc)
cross apply abc.nodes('/c/a') u (x)

这是通过使用仅针对(转换的)非嵌套逗号进行操作的XML切碎将字符串变形为XML来工作的,然后撤消XML化以恢复到原始格式。

我已经完成了几个单独的步骤,以便您可以看到XML标准化的中间阶段。

答案 3 :(得分:0)

使用以下功能获取行列表。会帮助

create FUNCTION [dbo].[spliting_function]
(
    @p_string VARCHAR(8000) -- List of delimited items
  , @sDelimiter VARCHAR(8000) = ',' -- delimiter that separates items
) RETURNS @List TABLE (item VARCHAR(8000))

BEGIN
DECLARE @sItem VARCHAR(8000)
WHILE CHARINDEX(@sDelimiter,@p_string,0) <> 0
 BEGIN
 SELECT
  @sItem=RTRIM(LTRIM(SUBSTRING(@p_string,1,CHARINDEX(@sDelimiter  ,@p_string,0)-1))),
  @p_string=RTRIM(LTRIM(SUBSTRING(@p_string,CHARINDEX(@sDelimiter,@p_string,0)+LEN(@sDelimiter),LEN(@p_string))))

 IF LEN(@sItem) > 0
  INSERT INTO @List SELECT @sItem
 END

IF LEN(@p_string) > 0
 INSERT INTO @List SELECT @p_string -- Put the last item in
RETURN
END


select item from dbo.spliting_function('a,b,c',',')