2015-03-06 2 views
2

У меня есть разделенные запятой столбец, который представляет идентификаторы городов, как:Получение значений, разделенных запятой полей в SQL Server

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

Я хочу, чтобы сделать запрос, чтобы получить имя поля это значение. Существует City таблицы, которая имеет два столбца: идентификатор и название города

ОЖИДАЕТСЯ ВЫХОД

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

я могу сделать запрос, если есть только один идентификатор в столбце, как:

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

, но я не получаю, как извлекать данные, если в одном поле есть несколько разделенных запятыми значений.

+2

Проект базы данных плохо, вы должны рассмотреть узнать о * нормализации *. – potashin

+0

Это может быть сложно обойтись без каких-либо фанковых запросов. Я бы, вероятно, вернул данные обратно в ваше приложение, и пусть он все сортирует и повторно запрашивает таблицу городов по мере необходимости, а затем приложите приложение к выходу, который вы хотите. –

+2

вы должны использовать данные в первой таблице для создания новой таблицы (один раз), которая затем может использовать стандартные объединения для получения ваших результатов. – Hogan

ответ

1

Простым способом является преобразование значений CSV в строки для каждого Идентификатора, соедините их с таблицей CITY и конвертируйте обратно в значений. Я написал логику внутри запроса.

;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 
  • Click here для просмотра результата
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 со ссылкой folwing
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 
+0

и сэр, как я могу использовать эту функцию? – user4410615

+0

Из всех возможных способов разделяя строки в sql, а версия nibbler, безусловно, хуже всего относится к производительности. См. эту статью для множества лучших опций. http: // sqlperformance.com/2012/07/t-sql-queries/split-strings –

+0

@ user4410615 проклятия вы можете сделать это без функции clr, но функция clr лучше –

Смежные вопросы