获取SQL Server中逗号分隔字段的值

时间:2015-03-06 20:54:18

标签: sql-server database

我有逗号分隔列,代表城市的ID,如:

ID | Name
1  | 1,2,3 
2  | 2,3,4

我想进行查询以获取此值字段的名称。有City表有两列:id和城市名称

预期输出

ID | VALUES    
1  | mumbai,delhi,pune
2  | delhi,pune,chennai

如果列中只有一个id,我可以进行查询:

select data.id,city.name from data,city where data.values=city.cityid

但如果一个字段中有多个以逗号分隔的值,我无法获取如何检索数据。

2 个答案:

答案 0 :(得分:1)

要做到这一点,请执行以下部分:
1 - 创建函数以获取每行中逗号表的单独值

CREATE FUNCTION [dbo].[fn_Split](
@ForigenKey INT,
 @String NVARCHAR (4000),
 @Delimiter NVARCHAR(10)
 )
RETURNS @ValueTable TABLE ([ID] INT IDENTITY NOT NULL,FID int null,[Value] NVARCHAR(4000))
BEGIN
 DECLARE @NextString NVARCHAR(4000)
 DECLARE @Pos INT
 DECLARE @NextPos INT
 DECLARE @CommaCheck NVARCHAR(1)

 --Initialize
 SET @NextString = ''
 SET @CommaCheck = RIGHT(@String,1) 

 --Check for trailing Comma, if not exists, INSERT
 --if (@CommaCheck <> @Delimiter )
 SET @String = @String + @Delimiter

 --Get position of first Comma
 SET @Pos = CHARINDEX(@Delimiter,@String)
 SET @NextPos = LEN(@Delimiter)

 --Loop while there is still a comma in the String of levels
 WHILE (@pos <>  0)  
 BEGIN
  SET @NextString = SUBSTRING(@String, 1, @Pos - 1)

  INSERT INTO @ValueTable ( FID,[Value]) VALUES (@ForigenKey ,@NextString)

  SET @String = SUBSTRING(@String,@pos + LEN(@Delimiter),LEN(@String))

  SET @NextPos = @Pos
  SET @pos  = CHARINDEX(@Delimiter,@String)
 END

 RETURN
END

GO

2-使用后续链接创建Concat Aggregate Concat Aggregate

3-您可以通过以下选择

获取您的数据
DECLARE @ID INT,@Name NVARCHAR(4000)
 DECLARE @ValueTable table ([ID] int NOT NULL,[Value] INT)
DECLARE mycur CURSOR FOR
SELECT TOP(1000) ID,Name FROM TableA
OPEN mycur
FETCH NEXT FROM mycur INTO @ID,@Name
WHILE(@@FETCH_STATUS=0)
BEGIN
    INSERT INTO @ValueTable
            ( ID, Value )
    SELECT @ID,Value FROM dbo.fn_Split(@Name,',')
    FETCH NEXT FROM mycur INTO @ID,@Name
END
CLOSE mycur
DEALLOCATE mycur
SELECT * FROM @ValueTable


SELECT ID,dbo.ConcatAggregate(CityName) FROM @ValueTable
inner join city on value=cityid GROUP BY ID

答案 1 :(得分:1)

简单的方法是将CSV值转换为每个Id的行,将其与CITY表连接并转换回CSV值。我在查询中写了逻辑。

;WITH CTE1 AS
(
    -- Convert CSV to rows
    SELECT Id,LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'NAME' 
    FROM  
    (
         -- To change ',' to any other delimeter, just change ',' before '</M><M>' to your desired one
         SELECT Id,CAST ('<M>' + REPLACE(Name, ',', '</M><M>') + '</M>' AS XML) AS Data 
         FROM #TEMP     
    ) AS A 
    CROSS APPLY Data.nodes ('/M') AS Split(a)
)
,CTE2 AS
(
    -- Now join the values in rows with Id in CITY table
    SELECT T.ID,T.NAME,C.CITYNAME
    FROM CTE1 T
    JOIN #CITY C ON T.NAME=C.ID
)
-- Now convert back to CSV format
SELECT DISTINCT ID,
 SUBSTRING(
            (SELECT ', ' + CITYNAME
            FROM CTE2 I  
            WHERE I.Id=O.Id             
            FOR XML PATH('')),2,200000) [VALUES]
FROM CTE2 O