我有逗号分隔列,代表城市的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
但如果一个字段中有多个以逗号分隔的值,我无法获取如何检索数据。
答案 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