Intereting Posts
Компонент .NET Query Builder Рекурсия CTE SQL Server 2008 SQL Server. Произошла ошибка при выполнении пакета. Сообщение об ошибке: Недопустимое имя каталога. Восстановить базу данных «Сбой восстановления для сервера» xxx » Информация об обновлении SQL с использованием другой записи из той же таблицы Пример для функции, возвращающей строку True iff Сохранение значений множественного выбора в базе данных Устранение неполадок вокруг сложного запроса на удаление SQL SQL Query, выбор 5 самых последних в каждой группе SQL – схема сообщений – необходимо найти существующий поток сообщений, заданный набором пользователей Странная проблема SQL2005. «SqlConnection не поддерживает параллельные транзакции» эквивалент generate_series () в DB2 Реальная, математическая «модульная» операция в Postgres? Запуск нескольких операторов SQL в одной операции Извлеките несколько строк с запросом с использованием AND и OR

Как разделить одну ячейку на несколько столбцов в SQL Server 2008R2?

Я хочу разделить каждое имя для отдельных столбцов

create table split_test(value integer,Allnames varchar(40)) insert into split_test values(1,'Vinoth,Kumar,Raja,Manoj,Jamal,Bala'); select * from split_test; Value Allnames ------------------- 1 Vinoth,Kumar,Raja,Manoj,Jamal,Bala 

Ожидаемый результат

 values N1 N2 N3 N4 N5 N6 N7.......N20 1 Vinoth Kumar Raja Manoj Jamal Bala 

используя этот пример, вы можете получить представление.

 declare @str varchar(max) set @str = 'Hello world' declare @separator varchar(max) set @separator = ' ' declare @Splited table(id int identity(1,1), item varchar(max)) set @str = REPLACE(@str,@separator,'''),(''') set @str = 'select * from (values('''+@str+''')) as V(A)' insert into @Splited exec(@str) select * from @Splited 

Вот инструкция sql, использующая рекурсивный CTE для разделения имен на строки, а затем сворачивает строки в столбцы. SqlFiddle

 with names as (select value, 1 as name_id, substring(Allnames,1,charindex(',',Allnames+',', 0)-1) as name, substring(Allnames,charindex(',',Allnames, 0)+1, 40) as left_names from split_test union all select value, name_id +1, case when charindex(',',left_names, 0)> 0 then substring(left_names,1,charindex(',',left_names, 0)-1) else left_names end as name, case when charindex(',',left_names, 0)> 0 then substring(left_names,charindex(',',left_names, 0)+1, 40) else '' end as left_names from names where ltrim(left_names)<>'') select value, [1],[2],[3],[4],[5],[6],[7],[8],[9] from (select value,name_id,name from names) as t1 PIVOT (MAX(name) FOR name_id IN ( [1],[2],[3],[4],[5],[6],[7],[8],[9] ) ) AS t2 

ОБНОВИТЬ

Ответ @ KM может быть лучшим способом разделения данных на строки без рекурсивной таблицы CTE. Он должен быть более эффективным, чем этот. Поэтому я следую этому примеру и упростил часть логики процесса с нулевым значением. Вот результат:

Шаг 1. Создание таблицы включает в себя все числа от 1 до номера больше, чем максимальная длина столбца Allnames .

 CREATE TABLE Numbers( Number int not null primary key); with n as (select 1 as num union all select num +1 from n where num<100) insert into numbers select num from n; 

Шаг 2. Присоедините данные таблицы split_test с таблицей чисел, мы можем получить все части, начиная с. Затем возьмите первую часть между 2 , сформируйте каждую строку. Если существуют нулевые значения, добавьте их с объединением.

 select value , ltrim(rtrim(substring(allnames,number+1,charindex(',',substring(allnames,number,40),2)-2))) as name from (select value, ','+allnames+',' as allnames from split_test) as t1 left join numbers on number<= len(allnames) where substring(allnames,number,1)=',' and substring(allnames,number,40)<>',' union select value, Allnames from split_test where Allnames is null 

Шаг 3. Обозначим имена из строк в столбцы, как моя первая попытка выше, опущена здесь. SQLFiddle